Alternativen in regulären Ausdrücken - Oder-Suche mit RegEx
Manchmal möchte man in regulären Ausdrücken eine Oder-Suche durchführen. Dies wird ermöglicht durch den |-Operator im Suchteil des regulären Ausdruckes.
Beispiel:
my $t="test";
if ($t=~ /haus|test|maus/){print "gefunden $&";} else {print "nicht gefunden";}
Es wird von links her nach dem passenden Ausdruck gesucht und wenn gefunden, die Suche abgebrochen. In $& steht das gesuchte Wort, in diesem Fall "test".
So weit, so gut.
Allerdings läuft die Sache im täglichen Leben nicht immer so einfach. Angenommen, man sucht das Wort "Programmtest" oder "Laufzeittest" oder "Perltest", also immer ein zusammengesetztes Wort mit test am Ende, so wäre es ja sinnvoll, einen regulären Ausdruck zu finden, der nach dem "test" am Ende sucht.
Wie Sie sehen, wird hier mit Klammern gearbeitet. In den Klammern stehen die verschiedenen Alternative, außerhalb der Klammer das gemeinschaftliche "test". Gerfunden wird wie gewünscht "Perltest".
Übrigens
Ein aufmerksamer Leser teilte mir folgendes mit:
Das zweite Beispiel schreibt man besser als
"Mit (?: ... ) bezeichnet man eine "Non-Capturing Group". Das heißt, der Match dieser Gruppierung landet in keiner Variablen. Hier wird vielmehr der komplette Match nach $1 gespeichert. So kann man Performance-Verluste vermeiden." Danke für den Hinweis!
Ich habe das mal zum Anlass genommen und es laufzeitmäßig durchgecheckt. Und bingo: Es stimmt! Die neuere Variante ist tatsächlich um ca. 20 % schneller (51 zu 60 Sekunden bei 50.000.000 Aufrufen)
Wie Sie sehen wird hier per index() nach den drei Werten gefragt.
Die letzte Variante ist wiederum ca. 25 % schneller und damit fast doppelt so schnell wie die ursprüngliche Variante. index () ist speziell für das Suchen in Zeichenketten konzipiert und es war deshalb abzusehen, daß es schneller ist. Aber das Beispiel hatte eben nichts mit RegEx zu tun, passt also nicht so hierher. Aber sollte ja trotzdem mal gesagt werden...
Ich denk gerade drüber nach, ein do und do-not der RegEx anzufangen, na denn mal los.