seth: Knifflige RegEx

Beitrag lesen

hi _Dirk!

s/(^|[^<])$x($|[^>])/$1#$x#$2/g;
die Antwort hatte mal Stil! Kurz und knackig. Ich würde mir sie beinahe auf ein T-Shirt drucken lassen,

du sagst das so einfach und meinst das wohl nicht wirklich ernst. aber es gibt tatsaechlich leute, die mit sowas auf t-shirts rumlaufen... vor kurzem habe ich gerade wieder gesehen: /(b{2}|[^b]{2})/

wenn ich auch nur ansatzweise wüsste, was der Zeichensalat da oben bewirkt

ich versuche dir nun mal _ansatzweise_ dabei zu helfen:
s/u/v/g heisst soviel wie: ersetze u durch v, sooft du es findest. (dabei steht das s fuer suchen und ersetzen, das g fuer die globale ersetzung)

spezifizieren wir nun u, also (^|[^<])$x($|[^>]):

allgemein:
a|b heisst: a oder b
^ steht fuer: textanfang
$ steht fuer: textende
[^c] spezifiziert: ein zeichen, dass kein c ist (das dach hat hier also nichts mit dem dach zu tun, welches "textanfang" bedeutet; hier bedeutet das dach eine negation)
die durch in runde klammern eingeschlossene ausdruecke gefundenen textstuecke werden automatisch gespeichert als $1 (erster durch klammern begrenzter ausdruck), $2 usw. gespeichert. (wird am beispiel gleich klarer)

(^|[^<]) heisst in etwa: textanfang oder ein zeichen, dass nicht < ist. die runden klammern bedeuten hier: speichere das gefundene in der variable $1.

entsprechend heisst ($|[^>]) in etwa: textende oder ein zeichen, dass nicht > ist. speichere das gefundene in $2.

das $x steht nur fuer den inhalt der variable $x.

somit heisst (^|[^<])$x($|[^>]) suche den inhalt von $x, wobei das zeichen davor (falls eines existiert) kein < sein darf und das zeichen danach (falls eines existiert) kein > sein darf. speichere dabei das zeichen vor $x in $1 und das zeichen nach $x in $2.

so kommen wir nun zu v, also $1#$x#$2

das bedeutet, dass sowohl zwischen $1 und $x als auch zwischen $x und $2 eine raute (bzw. ein doppelkreuz) eingefuegt werden soll.

zusammengesetzt heisst
s/(^|[^<])$x($|[^>])/$1#$x#$2/g;
somit in etwa:
suche den inhalt von $x, wobei das zeichen vor $x (falls eines existiert) kein < sein darf und das zeichen danach (falls eines existiert) kein > sein darf. speichere dabei das zeichen vor $x in $1 und das zeichen nach $x in $2. ersetze den kompletten gefunden ausdruck (also $1$x$2) durch $1#$x#$2.
diesen vorgang fuehre sooft durch, wie du $x findest.

oh, mann! perl ist doch saugeil, oder?

prost
seth

ps. habe mir mein geschriebenes jetzt gerade noch mal durchgelesen und bin zu dem schluss gekommen, dass http://www.perldoc.com viel besser und exakter erklaert als ich und zudem mir weniger arbeit bereitet haette. hihi, wie doof ;-)