Reguläre Ausdrücke sind ein mächtiges Werkzeug im Arsenal von Programmierern, aber - es gibt Fälle, in denen sie nicht die beste Wahl sind oder sogar geradezu schädlich.
Einfaches Beispiel # 1 analysiert HTML mit Regexp - ein bekannter Weg zu zahlreichen Fehlern. Wahrscheinlich ist dies auch auf das Parsen im Allgemeinen zurückzuführen.
Aber gibt es noch andere Bereiche, in denen reguläre Ausdrücke eindeutig verboten sind?
ps: " Die Frage, die Sie stellen, erscheint subjektiv und wird wahrscheinlich geschlossen. " - Ich möchte daher betonen, dass ich an Beispielen interessiert bin, bei denen die Verwendung von regulären Ausdrücken bekanntermaßen Probleme verursacht.
Antworten:
Verwenden Sie keine regulären Ausdrücke:
Dies ist nicht auf HTML beschränkt . Ein einfaches gültiges XML kann nicht mit einem regulären Ausdruck analysiert werden, selbst wenn Sie das Schema kennen und wissen, dass es sich niemals ändern wird.
Versuchen Sie beispielsweise nicht, C # -Quellcode zu analysieren . Analysieren Sie es stattdessen, um eine aussagekräftige Baumstruktur oder die Token zu erhalten.
Was ist, wenn Sie nach einem Buchstaben suchen müssen, der sowohl klein als auch groß ist? Wenn Sie reguläre Ausdrücke lieben, werden Sie sie verwenden. Aber ist es nicht einfacher / schneller / lesbarer, zwei Suchen nacheinander durchzuführen? Wahrscheinlich erzielen Sie in den meisten Sprachen eine bessere Leistung und verbessern die Lesbarkeit Ihres Codes.
Zum Beispiel ist der Beispielcode in Ingos Antwort ein gutes Beispiel, wenn Sie keine regulären Ausdrücke verwenden müssen. Einfach suchen
foo
, dann nachbar
.Ein gutes Beispiel ist ein Obszönitätsfilter. Es ist nicht nur eine schlechte Idee , es zu implementieren, sondern Sie könnten auch versucht sein, es mit regulären Ausdrücken zu tun, und Sie werden es falsch machen. Es gibt viele Möglichkeiten, wie ein Mensch ein Wort, eine Zahl oder einen Satz schreiben kann und von einem anderen Menschen verstanden wird, aber nicht von Ihrem regulären Ausdruck. Anstatt also echte Obszönität zu empfinden, verbringt Ihr regulärer Ausdruck Ihre Zeit damit, andere Benutzer zu verletzen.
Überprüfen Sie beispielsweise eine E-Mail-Adresse nicht mit einem regulären Ausdruck. In den meisten Fällen werden Sie es falsch machen. In seltenen Fällen werden Sie es richtig machen und mit einem 6 343 Zeichen langen Codierungshorror abschließen .
Ohne die richtigen Werkzeuge werden Sie Fehler machen. Und Sie werden sie im letzten Moment bemerken, oder vielleicht nie. Wenn Sie sich nicht für sauberen Code interessieren, schreiben Sie eine Zeichenfolge mit zwanzig Zeilen ohne Kommentare, ohne Leerzeichen und ohne Zeilenumbrüche.
Im Ernst, wenn ich Ihren Code nehme und ihn überprüfen oder ändern muss, möchte ich nicht eine Woche lang versuchen, eine zwanzig Zeilen lange Zeichenfolge mit vielen Symbolen zu verstehen.
quelle
(?(DEFINE))
Varianten), informieren Sie sich über Subroutinen, benannte Erfassungsgruppen und Behauptungen sehr ähnlich zu dem, was Sie in yacc oder ähnlich schreiben würden;)"<a href='foo'>stuff</a>"
. Moderne Regexes haben damit keine Probleme.Das Wichtigste: Wenn die Sprache, die Sie analysieren, keine reguläre Sprache ist .
HTML ist keine reguläre Sprache und das Parsen mit einem regulären Ausdruck ist nicht möglich (nicht nur schwierig oder ein Weg zum fehlerhaften Code).
quelle
Beim Stapelüberlauf werden häufig reguläre Ausdrücke abgefragt, die herausfinden, ob ein bestimmter String dieses oder jenes nicht enthält. Dies ist meiner Meinung nach eine Umkehrung des Zwecks des regulären Ausdrucks. Selbst wenn es eine Lösung gibt (unter Verwendung negativer Lookbehind-Behauptungen oder dergleichen), ist es oftmals viel besser, die Regex für das zu verwenden, wofür sie erstellt wurde, und den negativen Fall mit Programmlogik zu behandeln.
Beispiel:
quelle
Zwei Fälle:
Wenn es einfacher geht
Die meisten Sprachen bieten eine einfache Funktion wie INSTR, um festzustellen, ob eine Zeichenfolge eine Teilmenge einer anderen ist. Wenn Sie dies möchten, verwenden Sie die einfachere Funktion. Schreiben Sie nicht Ihren eigenen regulären Ausdruck.
Wenn eine Bibliothek zur Durchführung einer komplexen Zeichenfolgenmanipulation verfügbar ist, verwenden Sie diese, anstatt Ihren eigenen regulären Ausdruck zu schreiben.
Wenn reguläre Ausdrücke nicht mächtig genug sind
quelle
Reguläre Ausdrücke können keine rekursiven Strukturen identifizieren . Dies ist die grundlegende Einschränkung.
Nehmen wir JSON - es ist ein ziemlich einfaches Format, aber da ein Objekt andere Objekte als Elementwerte enthalten kann (willkürlich tief), ist die Syntax rekursiv und kann nicht von einem regulären Ausdruck analysiert werden. Andererseits kann CSV von regulären Ausdrücken analysiert werden, da es keine rekursiven Strukturen enthält.
Kurz gesagt, reguläre Ausdrücke lassen nicht zu, dass sich das Muster auf sich selbst bezieht. Sie können nicht sagen: An dieser Stelle in der Syntax stimmen Sie wieder mit dem gesamten Muster überein. Um es anders auszudrücken, reguläre Ausdrücke stimmen nur linear überein. Sie enthalten keinen Stapel, der es ermöglicht, zu verfolgen, wie tief ein verschachteltes Muster ist.
Beachten Sie, dass es nichts damit zu tun hat, wie komplex oder verworren das Format ansonsten ist. S-Ausdrücke sind wirklich sehr einfach, können aber nicht mit einem regulären Ausdruck analysiert werden. CSS2 hingegen ist eine recht komplexe Sprache, enthält jedoch keine rekursiven Strukturen und kann daher mit einem regulären Ausdruck analysiert werden. (Dies gilt jedoch nicht für CSS3, da CSS-Ausdrücke eine rekursive Syntax haben.)
Das liegt also nicht daran, dass es hässlich oder komplex oder fehleranfällig ist, HTML nur mit regulären Ausdrücken zu analysieren. Es ist einfach nicht möglich .
Wenn Sie ein Format analysieren müssen, das rekursive Strukturen enthält, müssen Sie die Verwendung regulärer Ausdrücke mindestens durch einen Stapel ergänzen, um die Ebene rekursiver Strukturen zu verfolgen. So funktioniert normalerweise ein Parser. Reguläre Ausdrücke werden verwendet, um die "linearen" Teile zu erkennen, während benutzerdefinierter Code außerhalb des regulären Ausdrucks verwendet wird, um die verschachtelten Strukturen zu verfolgen.
Normalerweise wird das Parsen so in separate Phasen aufgeteilt. Tokenisierung ist die erste Phase, in der reguläre Ausdrücke verwendet werden, um die Eingabe in eine Folge von "Token" wie Wörter, Interpunktion, Klammern usw. zu unterteilen. Parsing ist die nächste Phase, in der diese Token in eine hierarchische Struktur, einen Syntaxbaum, zerlegt werden.
Wenn Sie also hören, dass HTML oder C # nicht mit regulären Ausdrücken analysiert werden können, beachten Sie, dass reguläre Ausdrücke immer noch ein kritischer Bestandteil der Parser sind. Sie können eine solche Sprache nur mit regulären Ausdrücken und ohne Hilfscode analysieren .
quelle