Thema: umdrehen und filtern innerhalb einer substitution

nabend,<p>ich dreh echt noch am Rad. Ich probier seit drei Tagen ein Problem zu lösen und komm einfach nicht weiter. Vielleicht könnt ihr mir ja helfen. Ist echt ne Herausforderung, zumindest für micht.<p>also. Gegeben ist folgendes:<p><blockquote><font size="1" face="Verdana, Helvetica, sans-serif">Code:</font><hr><pre>
$_ = '#IORG# Geffert, Johannes #OD# Scheerer, Ingeborg #OR# Johann Christian Bach-Akademie';<p>%instrumente = ( '#IORG#' => 'Orgel',
                  '#OD#'   => 'Dirigent / Band Leader',
                  '#OR#'   => 'Orchester (Instrumentalensemble / Sinfonieorchester)');
</pre><hr></blockquote>
Dies sind auszüge aus einer sehr umfangreichen Liste die Kürzel für Instrumente beinhaltet und ein Auszug aus einer noch umfangreicheren Liste die für einen CD Titel (nicht mit aufgeführt) eine Liste von Artisten enthält.<p>Problemstellung:<p>es soll was in der Art:<p>Geffefert, Johannes (Orgel)<br>Scheer Ingeborg(Dirigent / Band)<br>Johann Christian Back Akademie(Orchester ...) <p>ausgegeben werden.
ich hab bis jetzt echt alles probiert.<p><blockquote><font size="1" face="Verdana, Helvetica, sans-serif">Code:</font><hr><pre>
foreach $s ( keys ( %instrumente) ) {
    s/$s/$instumente{$s}/ig;
}
</pre><hr></blockquote>
ersetzt mir zwar die Schlüssel der Instrumente aber die Reihenfolge stimmt nicht (Artist (Instrument)). Weiter werden auch durch die Zufälltige anordnug der Schlüssel im Hash %instrumente die Reihenfolge innerhalb des Eintrags durcheinadergewürfelt.<p>Weiter hatte ich echt total viele Ansätze die aber allesamt in die Hose gingen:<p>z.B
<blockquote><font size="1" face="Verdana, Helvetica, sans-serif">Code:</font><hr><pre>
while(/(#.+?#)/g) {
    s/($1)(.+?)#/$2$1#/;
}
</pre><hr></blockquote>
wär für mich auch logisch. Solange er ne # bis alles bis zu dem nächsten # findet soller sich das merken und das was er gemerkt hat durch das was folgt vertauchen /$2$1/ den # muss man meines erachtens noch dranhängen weil er sonst die nächste Zeichenfolge #xxx# nicht findet. <p>... Klappt aber auch nicht.<p>besser wärs ja noch so gewesen:<p><blockquote><font size="1" face="Verdana, Helvetica, sans-serif">Code:</font><hr><pre>
while(/(#.+?#)/g) {
    foreach $s (keys (%instrumente) ) {
       if($s eq $1) {
          s/($1)(.+?)/$instrumente{$s}$1/;
       }
    }
}
</pre><hr></blockquote><p>aber irgenwie klappt das alles nicht. Ich hab auch schon probiert die ganze Sache nach # in splitten zu lassen und nach (% 2 == 0) in zwei Arrays zu speichern und hinterher wieder zusammenzusetzen aber nix funzt. Ich bin echt am verzweifeln. <p>Wenn einer ne Idee hat wär echt super.<p>danke, sel.

2

Re: umdrehen und filtern innerhalb einer substitution

hm, ich habs mir grad nochmal durchgelesen, vielleicht noch zur erklärung:<p>in $_ steht der string um den es geht. Ich hab ne txt Datei mit 1600 Zeilen die bearbeitet werden müssen. Ich lass mir das ganze Zeugs in nen Array auslesen und in $$_[7] steht dann z.B das was ich oben in $_ gesetzt habe, aber das ist auch für die Sache nicht so relevant. <p>dann hab in ne Datei mit den ganze Schlüsseln für #xyz# etc. Die lass ich auch einlesen und speicher alles in einem Hash %instrumente wobei #xyz# der Schlüssel und 'IxÜpsilonZet' der Wert ist. Ich muss jetzt in jeden String der in $$_[7] steht die Schlüssel - Wert Paare tauschen und ausser dem den ausgetauschten Wert mit den folgenem String bis zum nächsten Schlüssel umdrehen...<p>btw: Ich bin trotz allem saufroh dass ich das nicht mit php proggen muss.  [img]images/icons/smile.gif" border="0[/img] <p>cu, sel.

3

Re: umdrehen und filtern innerhalb einer substitution

Tach Sel,

Wie wär's, wenn Du Dir statt des hashs ne subroutine schreibst, etwa so:

$_ = '#IORG# Geffert, Johannes #OD# Scheerer, Ingeborg #OR# Johann Christian Bach-Akademie';

sub ES(){$_=~s/#$_[0]#([^#]+)/<nobr>$1 <tt  style='color:red'>($_[1])</tt></nobr><br>/;};

&ES('IORG','Orgel');
&ES('OD','Dirigent / Band Leader');
&ES('OR','Orchester (Instrumentalensemble / Sinfonieorchester)');

print $_;

Das bringt Dir Reihenfolge nicht durcheinander.

gruß

matho

4

Re: umdrehen und filtern innerhalb einer substitution

matho ist einfach genial!  <img border="0" title="" alt="[Winken]" src="images/icons/wink.gif" />

_______________________________________________________________

/-/annes (j|g) ... http://www.jg-webdesign.de

5

Re: umdrehen und filtern innerhalb einer substitution

Danke für die Blümelein,

Mir ist noch was eingefallen,
man kann das ja ein wenig komfortabler machen:

$_ = '#IORG# Geffert, Johannes #OD# Scheerer, Ingeborg #OR# Johann Christian Bach-Akademie';

@I =
(
'IORG', 'Orgel',
'OD',   'Dirigent / Band Leader',
'OR',   'Orchester (Instrumentalensemble / Sinfonieorchester)'
);

for($i=0;$i<@I/2;$i++)
{$_=~s/#@I[$i*2]#([^#]+)/<nobr>$1 <tt  style='color:red'>(@I[$i*2+1])</tt></nobr><br>/;};

print $_;

Dann hättest Du Deinen hash, bloß eben als array.

und nochen gruß

matho

6

Re: umdrehen und filtern innerhalb einer substitution

Ja, echt prima. Wirklich Klasse mir mit einem Posting alles das zu nehmen was ich mir dachte über arbeitsweise der $_ und regExps angeignet zu haben. :-/

Nein, schönen Dank fürs Post.  <img border="0" title="" alt="[Lächeln]" src="images/icons/smile.gif" />

Aber nen paar Sachen verhalten sich hier anders als ich gedacht hätte.

Zunächst die $_:

Wieso kommt kann ich auf die in der Routine zugreifen. Ich dachte in dem Moment, wo man in den Geltungsbereich der @_ kommt, verliert $_ die Gültigkeit. Weiter versteh ich nicht wieso man anscheinend mit einer Referenz auf $_ und nicht mit einem Call bei Value arbeitet. Wenn ich das hätte machen sollen, hätt ich $_ brav als Parameter übergeben und zum Schlu� brav returnt.

Zum regulären Ausdruck:

#$_[0]#

is klar.

mein Fehler war (unter anderem), das ich über eine Anweisung wie:

#$s#(.+?)(#|$)#/$instrumente{$s}$1$2/ig;

Das was ich merke nur bis zu der nächsten Fundstelle eines # haben wollte. Das gab natürlich probleme wenn ich die Musiker der Nächstes Kürzels finden wollte, der reguläre Ausdruck aber natürlich alle schon übersetzten Schlüssel mitgesaugt hat.

Wenn ich das richtig verstehe, dann merkst du dir über

([^#]+) den rest des Strings und setzt in hintendran wieder ein.

Neinnein, stimmt gar nicht, das ^ in der Zeichenklasse steht ja für alle Zeichen ausser den angegebenen. Und dann merkst du dir doch nicht den ganze String sondern genauso wie ich alles bis zum nächsten #xxx#. Bei der Methode wird blo� die Reihenfolge beibehalten und deshalb kommts blo� nicht durcheinander.

Manman. Ich werds am WE mal probieren einzubauen.

erstmal danke,

sel,

btw:

Ich find den call ne bisschen umständlich da es wie gesagt eine ganze Liste von Kürzel ist, aber man könnt deine Funktion ja auch gut so unterbringen:

open(KUERZEL, $kuerzeldatei) or die ("Shit, $!");
while($zeile = <KUERZEL>) {
chomp($zeile);
ES(split(/ +/, $zeile);
}

die Schlü�el - Wert Paare liegen alle in ner Datei durch Leerzeichen getrennt.

Naja, wird wohl klappen. Wenn nicht werd ich mich auf jeden Fall noch mal melden,

thx, sel.