Reguläre Ausdrücke

mdo

Mitglied
Hallo!
Ich bin am verzweifeln und weiß nicht, ob das überhaupt mit regulären Ausdrücken geht...

Also folgendes:

Ich will in einem Text Platzhalter ersetzen. Ein Platzhalter fängt immer mit "<<" an und hört mit ">>" auf. Das ganze wird mit dem Regulären Ausdruck: "((<<)|(<\|))[^>>|\|>]*((>>)|(\|>))" auch korrekt erkannt.

Nun will ich aber übergeordnete Platzhalter einführen. Diese beginnen mit "<<[[" und enden mit "]]>>". Diese können andere Platzhalter enthalten, diese inneren Platzhalter sollen aber nicht erkannt werden!

Beispieltext:
<<[[Ich bin ein Beispiel <<P1>>, <<P2>> Platzhalter!]]>> <<P3>>, <<P4>>

Bedeutung:
<<[[Ich bin ein Beispiel <<P1>>, <<P2>> Platzhalter!]]>> => Beispiel
<<P1>> => "Platzhalter 1"
<<P2>> => "Platzhalter 2"
<<P3>> => "Platzhalter 3"
<<P4>> => "Platzhalter 4"

Gewünschtes Ergebnis:
Beispiel Platzhalter 3, Platzhalter 4

Bitte nicht über Sinn oder Unsinn streiten, das Beispiel ist total aus dem Zusammenhang gerissen ;)

Das Problem dabei ist, dass er den Platzhalter "<<[[Ich bin ein Beispiel <<P1>>, <<P2>> Platzhalter!]]>>" nicht als solchen erkennt. Das beste Ergebnis bisher (nicht der oben genannte RegEx) lieferte als gefundenes Ergebnis: "<<[[Ich bin ein Beispiel <<P1>>"...

Kann mir jemand sagen, ob meine gewünschte Funktion überhaupt möglich ist? Und eventuell ein wenig helfen? Ich spring gleich aus dem Fenster!

Danke!
mdo
 
Ich habs! Nach noch ein wenig Schweiß und Blut hab ichs raus bekommen! Hier der finale Regex, für alle, die ähnliche Probleme haben:
(((<<\[\[)[^(\[\[|\]\])]*(\]\]>>))|(((<<)|(<\|))[^(>>|\|>|\[\[|\]\])]*((>>)|(\|>))))

MUHAHAHA!
 
Huhu,
ich weiß du hast eine Lösung, aber hier ein Vorschlag für einen Ausdruck, welcher mir persönlich verständlicher, professioneller und vorallem kürzer erscheint:
Code:
(<<\[\[.*?\]\]>>)|(<<.*?>>)

Wichtig sind hier 2 Dinge:
1. In der Oder-Verknüpfung überprüft er zuerst den linken Anteil, d.h. hier muss das übergeordnete Tag stehen.
2. Non-greedy Operator ("<<.*?>>" statt "<<.*>>"):
Bsp. <<P1>><<P2>> statt <<P1>><<P2>>
 
Für Alternativen bin ich immer dankbar!
Das mit dem übergeordneten Tag ist mir klar, das ist mir kurz nach dem Verfassen des Threads eingeleuchtet.
Allerdings weiß ich nicht genau was du mit dem ".*?" tun willst!?
"?" bedeutet 0 oder 1 mal das vorangegangene Zeichen
"*" bedeutet 0 oder n mal das vorangegangene Zeichen
"." bedeutet ein "beliebiges" Zeichen

Meiner Logik nach, müsste das "?" also eigentlich unnötig sein, oder?

Das würde auch zu deinem "Bsp" passen:
Bsp. <<P1>><<P2>> statt <<P1>><<P2>>
Ich seh da keinen Unterschied ^^

Aber btw:
Es geht ja scheinbar auch um das: "[^(\[\[|\]\])]*" bzw um das "[^(>>|\|>|\[\[|\]\])]*". Das soll bedeuten, dass die Zeichenfolgen [[ oder ]] bzw >> oder |> oder [[ oder ]] im Inneren nicht vorkommen dürfen. Würde man das ignorieren und die alternativen Begin udn Endtags (<| und |>) und auch noch die überflüssige Klammerung, wäre meine Lösung dementsprechend natürlich folgende:
(<<\[\[.*\]\]>>)|(<<.*>>)

Allerdings ist mir der Sinn des "?" immer noch nicht so ganz and er Stelle klar. Wo ist da der Mehrwert?
 
Zuletzt bearbeitet:
Ich wollte dir den Unterschied mit den fett gedruckten Zeichen klar deutlich machen, anscheinend ist mir das nicht gelungen, tut mir leid :)
Sagen wir du hast folgende Zeichenfolge: <<P1>>, <<P2>>
Fall1: <<.*>>
Du findest 1 Treffer, da dein String mit << beginnt und mit >> aufhört. Die << und >> dazwischen zählen mit zu den beliebigen Zeichen.
Fall2: <<.*?>>
Du findest 2 Treffer, eben weil .*? "non-greedy" grob zu deutsch "nicht gierig" ist.
 
Aha! Das heißt also, ich könnt "[^(\[\[|\]\])]*" bzw "[^(>>|\|>|\[\[|\]\])]*" einfach mit ".*?" ersetzen?
Also sind folgende Ausdrücke beide hinreichend? (siehe meine Definition vom vorherigen Post)
Code:
(<<\[\[[^(\[\[|\]\])]*\]\]>>)|((<<|<\|)[^(>>|\|>|\[\[|\]\])]*(>>|\|>))
und
Code:
(<<\[\[.*?\]\]>>)|(<<.*?>>)


Übrigens:
Auf meinem Monitor sehe ich keine fetten Zeichen in deinem Post, aber ich denke mal du meintest damit dann wohl die hier: <<P1>><<P2>>
 
Ja im Post #3 hatte ich die Zeichen fett gedruckt. Es geht hierbei genau um diese inneren Zeichen.

Aha! Das heißt also, ich könnt "[^(\[\[|\]\])]*" bzw "[^(>>|\|>|\[\[|\]\])]*" einfach mit ".*?" ersetzen?

Ja, allerdings musst du hier noch deine Variante mit |> bedenken, die hatte ich in meinem Ausdruck nicht mit drin, da ich nur auf deinen Beispiel-String eingegangen bin. Ich denke aber das Prinzip ist klar...
 
Zurück