RegEx - Ausdruck 2 mal eretzen

Hallo - ich mal wieder! :smile:
Wie schon gesagt, will ich einen Ausdruck sozusagen 2 mal ersetzen:

$message =~ s/() ([^]*) ()/g;

Also das, was in der 2. Klammer steht soll noch mal ersetzt werden und zwar mit tr///. $2 ist ja read_only - man kann die Variable also nicht verÀndern.
Wie lÀsst sich das lösen?

Mal wieder Danke im Vorraus

Christoph

Hallo,

Hallo - ich mal wieder! :smile:
Wie schon gesagt, will ich einen Ausdruck sozusagen 2 mal
ersetzen:

> $message =~ s/() ([^]\*) ()/g;

Also das, was in der 2. Klammer steht soll noch mal ersetzt
werden und zwar mit tr///. $2 ist ja read_only - man kann die
Variable also nicht verÀndern.
Wie lÀsst sich das lösen?

Mit den /e-Modifier, der dafĂŒr sorgt, dass die rechte Seite des Regex-Operators wie ganz normaler Perl-Code ausgefĂŒhrt wird. Also
$message =~ s/(
) (
) (
)/subst_funktion($1, $2, $3)/g;
sub subst_funktion {
my ($m1, $m2, $m3) = @_;
$m2 =~ tr/bar/foo/

wichtig: am Ende einen String zurĂŒckgeben:

return join(’|’, $m1, $m2, $m3);
}

HTH,
Moritz

Boah - wie geil is das denn.
Ich danke vielmals - genau das, was ich gesucht hab.
mfg Christoph

Hallo

Wie schon gesagt, will ich einen Ausdruck sozusagen 2 mal
ersetzen:

$message =~ s/() ([^]*) ()/g;

Also das, was in der 2. Klammer steht soll noch mal ersetzt
werden und zwar mit tr///. $2 ist ja read_only - man kann die
Variable also nicht verÀndern.
Wie lÀsst sich das lösen?

Moritz hat ja eine (imho zu komplizierte) Variante
angegeben, ich wĂŒrde es aber möglicherweise einfacher
machen (ich bin nicht sicherm ob Moritz’ Variante
in /g bei StringlĂ€ngenverĂ€nderung ĂŒberhaupt
funktioniert - kann aber durchaus sein):

 ...
 while( $message =~ /([^/g ) {
 my $p = pos $message;
 substr($message, $-[1], $+[1]-$-[1]) =~ tr/a-z/A-Z/;
 pos $message = $p
 }
 ...

Normalerweise „resetted“ eine VerĂ€nderung an $message
dessen pos(), also die skalare Position des
Matchoperators. Wenn wir einfach dieses pos()
aufheben und neu angeben, funktioniert es.

Der Ausdruck substr($message, $-[1], $+[1]-$-[1]) ist
genau der Bereich, der $1 entspricht. Hier werden
die Positionsfelder @- und @+ benutzt.

GrĂŒĂŸe

CMБ

Moritz hat ja eine (imho zu komplizierte) Variante
angegeben,

ich finde seine lösung verstÀndlich.

ich wĂŒrde es aber möglicherweise einfacher
machen (ich bin nicht sicherm ob Moritz’ Variante
in /g bei StringlĂ€ngenverĂ€nderung ĂŒberhaupt
funktioniert

tut sie - warum auch nicht? nicht jeder ersetzte string
muss die gleiche lÀnge haben wie der originalstring.
und ĂŒberhaupt - was ist an moritz’ lösung so schlecht?
magst du generell keine funktionen in ersetzungen aufrufen?

s/(wort)/length($1)/eg; # völlig legitim
  • kann aber durchaus sein):



while( $message =~ /([^/g )
{
my $p = pos $message;
substr($message, $-[1], $+[1]-$-[1]) =~ tr/a-z/A-Z/;
pos $message = $p
}



also ich weiss nicht, was *daran* jetzt einfacher sein soll =)

1 Like

Mit den /e-Modifier, der dafĂŒr sorgt, dass die rechte Seite
des Regex-Operators wie ganz normaler Perl-Code ausgefĂŒhrt
wird. Also

[
]
wobei du in deinem beispiel genau diesen e-modifier vergessen hast =)

Hallo Tina,

Moritz hat ja eine (imho zu komplizierte) Variante
angegeben,

ich finde seine lösung verstÀndlich.

tut sie - warum auch nicht? nicht jeder ersetzte string
muss die gleiche lÀnge haben wie der originalstring.
und ĂŒberhaupt - was ist an moritz’ lösung so schlecht?
magst du generell keine funktionen in ersetzungen aufrufen?

Schon, ich mach das auch gerne gelegentlich - aber
Du hast recht - es war ja ein tr// gefordert und bei
diesem bleibt ja auch die StringlÀnge identisch.

Irgendwas hatte meiner Ansicht nach nicht an Moritz’ Version
funktioniert (glaubte ich zu sehen) - aber nach eingÀngiger
PrĂŒfung (durch Deinen Hinweis - danke) denke ich, das die
Version von Moritz doch u.U. die bessere Variante ist.
Meine Interpretation der Moritzschen variante:

 ...
 $message =~ s/()([^)/subst\_funktion($1,$2,$3)/eg; 
 
 sub subst\_funktion {
 (local $\_=[@\_])-\>[1] =~ tr/a-z/A-Z/;
 return "@$\_"
 }
 ...

Sorry fĂŒr meine vorschnelle Äusserung. Ich werd das
hÀndisch mit Sternchen abarbeiten :wink:

GrĂŒĂŸe

CMБ

Schon, ich mach das auch gerne gelegentlich - aber
Du hast recht - es war ja ein tr// gefordert und bei
diesem bleibt ja auch die StringlÀnge identisch.

also um genau zu sein bleibt bei einem tr/// die lÀnge nicht immer identisch
(modifier /d und /s z.b.)
aber das muss sie auch gar nicht, es funktioniert so oder so.

Hallo Tina,

also um genau zu sein bleibt bei einem tr/// die lÀnge nicht
immer identisch (modifier /d und /s z.b.)
aber das muss sie auch gar nicht, es funktioniert so oder so.

Richtig, wer weiss, was vorhin mit mir los
war 
( zu viel anderen Kram gleichzeitig
um die Ohren). Irgendwie schwirrte mir die
Substitution „direkt im String-SV*“ im
SchÀdel rum, daher mein geÀusserter Quark.

OK, zum Abschluss die getunte „Moritzsche Variante“ dafĂŒr :wink:

 ...
 sub xeeg { '($\_=$2)=~tr/a-z/A-Z/;"$1$\_$3"' }
 ...
 $message =~ s/() ([^)/xeeg/geex;
 ...

Aber trotzdem vermute ich, dass der OP
gerade ein XY-Problem löst 
 :wink:

GrĂŒĂŸe

CMБ

Addendum

Das:



sub xeeg { ‚($_=$2)=~tr/a-z/A-Z/;"$1$_$3"‘ }


$message =~ s/() ([^)/xeeg/geex;

klĂ€ĂŸt sich auch direkt

 ...
 $message =~ s{()([^)}{'(local$\_=$2)=~y/a-z/A-Z/;"$1$\_$3"'}gee;
 ...

ausdrĂŒcken.

GrĂŒĂŸe

CMb