Spass mit regulären Ausdrücken

In Allerlei

Bisher dachte ich ja, dass ich mich mit regulären Ausdrücken ganz gut auskenne. Heute allerdings stand ich dann vor einem Problem, was sich nicht so leicht lösen lässt, denn ich hatte ungefähr Folgendes zu lösen:


Text 1: Horst - Foo
Text 2: Horst - Foo/Bar

Und jetzt brauchte ich einen Ausdruck, der zwar Text 1 erkennt, aber Text 2 nicht. Das ist gar nicht so einfach, da man zwar in einem Zeichenbereich angeben kann, dass etwas nicht matchen soll, aber einen ganzen String ausschließen? Das war mir zumindest bis jetzt nicht bekannt.

Es geht aber, und zwar mit etwas, das sich negative Lookahead nennt. Das Ergebnis sieht dann so aus:


Foo(?!.*?Bar)

Wenn man das mal auseinandernimmt, bedeutet es folgendes:

  1. Foo ist klar, das trifft halt auf Foo zu (ach was).
  2. Das (?!...) definiert den negativen Lookahead. Das ! sorgt dabei für die von mir gewünschte Negierung, wenn das nicht da wäre, wäre es ein positiver Lookahead, den es auch gibt
  3. Das .*? in der Subexpression sorgt dann noch dafür, das vor dem Bar beliebige Zeichen kommen dürfen, aber das Ganze soll nicht greedy sein.

Fein Testen konnte ich das mit dem Regular Expression Evaluator Rex V, sehr nettes Tool, mit dem man Live seine Ausdrücke ausprobieren kann. Und Regular-Expressions.info war auch sehr hilfreich dabei.

Als letztes musste ich dann nur noch sehen, dass es so auch in Java funktioniert, das war aber keine Problem, da ab Java 1.4 die Lookaheads in der Regular Expressions unterstützt wurden, was ich mit einem kleinen JUnit-Test für mich dann auch noch verifiziert habe.

Und notwendig ist dieses Rumgehampele mit den Regular Expressions auch nur, weil es für den Datenaustausch-Teil, den ich da grad programmieren muss, keinerlei definierte Schnittstelle gibt, sondern das mit Emails und angehängten Excel-Tabellen (ja, Excel, kein CSV!) funktioniert. Ich liebe solche tollen Systeme (Sarkasmus bitte selbst denken).

[File under: Nerdism]