Methode 1: Eine Regex anhand früherer Erfahrungen aufbauen

(Auszug aus "Reguläre Ausdrücke" von Jeffrey E. F. Friedl)

Bei der Analyse von ˹"(\\.|[^\\"]+)*"˼ ist es lehrreich, sich einige Strings vorzunehmen und zu sehen, welche der Unterausdrücke wirklich verwendet werden. Bei ›"Hallo!"‹ zum Beispiel ist der tatsächlich benutzte Ausdruck allein ˹"[^\\"]+"˼. Beim gefundenen Treffer wurde also nur das ˹"˼ am Anfang, einmal die Alternative ˹[^\\"]+˼ und dann das abschließende ˹"˼ benutzt. Bei

"Er sagte \"Hallo!\" und ging"

sind das ˹"[^\\"]+\\.[^\\"]+ \\.[^\\"]+. Hier und in der folgenden Tabelle sind die benutzten Unterausdrücke markiert. Es wäre schön, wenn wir für jeden Suchstring eine maßgeschneiderte Regex hätten. Das ist natürlich nicht möglich, aber wir können dennoch nach häufig vorkommenden Mustern suchen und damit einen schnelleren, aber doch äquivalenten Ausdruck aufbauen.

Tabelle: Beispiele für das Aufbrechen einer Schleife.

Suchstring Eigentlich benutzte Regex
"Hallo!" "[^\\"]+"
"Nur ein \" hier" "[^\\"]+\\.[^\\"]+"
"Ein \"sog.\" Ding" "[^\\"]+\\.[^\\"]+ \\.[^\\"]+"
"Von \"A\" nach \"B\"." "[^\\"]+\\.[^\\"]+ \\.[^\\"]+ \\.[^\\"]+ \\.[^\\"]+"
  
"\"ok\"\n" "\\.[^\\"]+ \\. \\."
"Leere \"\" Gänsefüßchen" "[^\\"]+\\. \\.[^\\"]+"

Wir konzentrieren uns zunächst auf die ersten vier Beispiele aus der obigen Tabelle. Die unterstrichenen Teile erkennen »ein geschütztes Zeichen, gefolgt von einer Anzahl normaler Zeichen«. In jedem Fall beginnt der Ausdruck zwischen den Anführungszeichen mit ˹[^\\"]+˼, und dann folgt eine Reihe von ˹\\.[^\\"]+˼-Sequenzen. Als regulärer Ausdruck formuliert, hieße das ˹[^\\"]+(\\.[^\\"]+)*˼. Hier ist für einen Spezialfall das Prinzip dargestellt, nach dem man häufig vorgehen kann.

Allgemeines Vorgehen beim Aufbrechen von Schleifen

Beim Erkennen von Strings in Anführungszeichen sind das Anführungszeichen selbst und allenfalls vorkommende geschützte Zeichen »speziell« – das Anführungszeichen, weil es den String abschließt, und der Backslash, weil er besagt, dass das Zeichen danach den String eben nicht abschließt. Alles andere, nämlich ˹[^\\"]˼, ist »normal«. Wenn wir darauf achten, wie aus diesen Zeichen ˹[^\\"]+(\\.[^\\"]+)*˼ zusammengesetzt wurde, erkennen wir ein zugrunde liegendes Muster: ˹normal+(speziell normal+)*˼.

Zusammen mit den Begrenzungszeichen erhalten wir ˹"[^\\"]+(\\.[^\\"]+)*"˼. Leider erkennt dieser Ausdruck die zwei letzten Beispiele in der obigen Tabelle nicht. Das liegt daran, dass unser neuer Ausdruck nach dem Anführungszeichen am Anfang des Strings und nach jedem geschützten Zeichen ein normales Zeichen verlangt. Das ist bei diesen zwei Beispielen nicht gegeben – ein String darf sehr wohl zwei geschützte Zeichen nacheinander enthalten oder ein geschütztes Zeichen gleich nach dem ersten Anführungszeichen.

Wir könnten die Pluszeichen durch Sterne ersetzen: ˹"[^\\"]*(\\.[^\\"]*)*"˼. Hat das den gewünschten Effekt? Noch wichtiger: Hat es unerwünschte Nebenwirkungen?

Soweit es erwünschte Wirkungen angeht, ist leicht zu sehen, dass jetzt alle Strings erkannt werden. Sogar ein String wie "\"\"\"" passt jetzt. So weit, so gut. Wir können aber so eine Änderung nicht vornehmen, ohne genau zu prüfen, ob sich dadurch Unvorhergesehenes einschleicht. Wird jetzt etwas anderes als ein String in Anführungszeichen erkannt? Gibt es zulässige Strings, die nicht erkannt werden? Wie steht es mit der Effizienz?

Betrachten wir ˹"[^\\"]*(\\.[^\\"]*)*"˼ genau. Das ˹"[^\\"]*˼ zu Beginn passt genau einmal und sieht harmlos aus: Es findet das geforderte Anführungszeichen am Anfang und mögliche normale Zeichen danach. Keine Gefahr. Das folgende ˹(\\.[^\\"]*)*˼ ist durch (...)* eingeklammert und kann deswegen auch auf »gar nichts« passen. Wenn es weggelassen wird, muss noch immer ein korrekter regulärer Ausdruck übrig bleiben. Wenn wir das tun, erhalten wir ˹"[^\\"]*"˼, das zweifelsohne korrekt ist – es passt auf den Normalfall, wenn keine geschützten Zeichen im String vorkommen.

Wenn umgekehrt der Ausdruck ˹(\\.[^\\"]*)*˼ einmal passt, ergibt sich als eigentliche Regex ˹"[^\\"]*\\.[^\\"]*. Auch wenn das ˹[^\\"]*˼ auf »gar nichts« passt (das ergibt die eigentliche Regex ˹"[^\\"]*\\.), entstehen keine Probleme. Wenn wir die Analyse in dieser Art fortführen (wenn meine Erinnerung an den Algebra-Unterricht nicht trügt, heißt das »Beweis durch vollständige Induktion«), stellen wir fest, dass diese Umformung tatsächlich korrekt ist.

Wir bekommen damit den folgenden Ausdruck für das Erkennen eines Strings in Anführungszeichen, der geschützte Anführungszeichen enthält:

˹"[^\\"]*(\\.[^\\"]*)*"˼

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema Reguläre Ausdrücke bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:
   

Copyright der deutschen Ausgabe © 2008 by O’Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "Reguläre Ausdrücke" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O’Reilly Verlag GmbH & Co. KG, Balthasarstr. 81, 50670 Köln