Sonntag, November 20, 2005

Regular Expressions - Spitzfindigkeiten

Angestossen durch eine Anfrage von Kollege Burgdorfer kam das Thema Regular Expressions (dt. Reguläre Ausdrücke) wieder einmal auf's Tapet. Aus meiner Sicht übrigens einer der genialsten Erfindungen, seit es Computer gibt - doch für Anfänger und auch Fortgeschrittene immer noch eine Knacknuss. "It just works" jedenfalls können Regex nicht für sich beanspruchen. Der Benutzer sollte also halbwegs eine Ahnung haben, was er da mit Hilfe von Voodoo alles zu Stande bringt.

Ausdrucks-Hilfen

Burgdorfer fand prompt ein nettes kleines Tool für Mac OS X, das dem Lernenden aufzeigt, ob sein Ausdruck in etwa funktioniert oder nicht:

RegexPlor

Ein kniffliger Ausdruck

Burgdorfer wollte anschliessend einen Substring aus einem String herausfiltern, der zwischen zwei bekannten Wörtern eingeklemmt ist, als Beispielsweise

google is considered to be very bad

Der Ausdruck, den ich ihm vorschlug und mit RegexPlor testete lautete deshalb

google(.+)bad

Das funktionierte erstaunlicherweise auf Anhieb einwandfrei.

Ich erinnerte mich aber an eine eigene, weiterführende Aufgabenstellung, die ich vor einiger Zeit zu bewältigen hatte - ich hatte Teile von HTML-Source-Code zu filtern. Das Problem war hier, dass mich ein zwischen einem bekannten Tag eingeschlossenen String interessierte, der Endtag aber dutzende Male im Dokument vorkam. Der Reguläre Ausdruck lieferte deshalb als Antwort den ganzen String bis zum letzten Vorkommen des Endtags zurück. In unserem Beispiel also:

google is considered to be very bad
although there seem to be even more bad ass
giants like microsoft who are much more
dangerously bad

Die Lösung hatte ich damals durch einige längere Recherchen im Netz gefunden, sie aber in der Zwischenzeit wieder vergessen. In irgendeinem PHP-File steht der Suchstring noch, doch ich konnte mich leider nicht mehr erinnern, in welcher meiner hunderten PHP-Dateien genau. Etwas später kam mir der zündende Gedanke und ich fand das fehlende Zeichen wieder:

google(.+?)bad

Das zusätzlich angefügte Fragezeichen weist den Interpreter an, nur bist zum ersten Vorkommen des Delimiters zu suchen:

google is considered to be very bad
although there seem to be even more bad ass
giants like microsoft who are much more
dangerously bad

3 Kommentare | neuen Kommentar verfassen

Kommentare

neuen Kommentar verfassen

Blogger christoph um 21.11.2005 00:51:00 Uhr

Und hier meldet sich "Kollege Burgdorfer" grad zu nochmals zu Wort: ein ueberaus nuetzlicher regex ist auch

< a \ s [ ^ > ] * h r e f = ( \ " ? ? ) h t t p : \ / \ / ( [ ^ \ " > ] * ? ) \ \ 1 [ ^ > ] * > ( . * ) < \ / a >

um alle links eines html Codes herauzufiltern. (mit Matches) In PHP wuerde sowas dann etwa so aussehen:

$regexp = "< a \ s [ ^ > ] * h r e f = ( \ " ? ? ) h t t p : \ / \ / ( [ ^ \ " > ] * ? ) \ \ 1 [ ^ > ] * > ( . * ) < \ / a >
";

preg_match_all("/$regexp/siU", $res, $matches);
# $matches[2] = array of link addresses
# $matches[3] = array of link text - including HTML code

viel Spass!

PS: der HTML filter hat es mir nicht erlaubt, den Regex normal zu posten, so habe ich ein Leerzeichen " " zwischen jedes Zeichen innerhalb des Regex gefuegt. Diese muessen natuerlich im effektiven Einsatz wieder rausgeloescht werden.

Anonymous Anonym um 21.11.2005 16:54:00 Uhr

das "voodoo" gefällt mir.

Anonymous Anonym um 05.12.2007 14:13:00 Uhr

Danach habe ich lange gesucht.
Danke!

Zitierungen dieses Artikels