it-swarm.dev

Wann sollten Sie KEINE regulären Ausdrücke verwenden?

Reguläre Ausdrücke sind ein mächtiges Werkzeug im Arsenal von Programmierern, aber - in einigen Fällen sind sie nicht die beste Wahl oder sogar geradezu schädlich.

Einfaches Beispiel Nr. 1 ist das Parsen von HTML mit regulärem Ausdruck - ein bekannter Weg zu zahlreichen Fehlern. Wahrscheinlich wird dies im Allgemeinen auch Parsing zugeschrieben.

Aber gibt es andere eindeutig No-Go-Bereiche für reguläre Ausdrücke?


ps: " Die Frage, die Sie stellen, erscheint subjektiv und wird wahrscheinlich geschlossen." - daher möchte ich betonen, dass ich an Beispielen interessiert bin, bei denen die Verwendung von regulären Ausdrücken bekanntermaßen dazu führt Probleme.

50
c69

Verwenden Sie keine regulären Ausdrücke:

  • Wenn es Parser gibt.

Dies beschränkt sich nicht auf HTML . Ein einfaches gültiges XML kann nicht angemessen mit einem regulären Ausdruck analysiert werden, selbst wenn Sie das Schema kennen und wissen, dass es sich niemals ändern wird.

Versuchen Sie zum Beispiel nicht C # -Quellcode analysieren . Analysieren Sie es stattdessen, um eine aussagekräftige Baumstruktur oder die Token zu erhalten.

  • Allgemeiner, wenn Sie bessere Werkzeuge haben, um Ihre Arbeit zu erledigen.

Was ist, wenn Sie nach einem kleinen und einem großen Brief suchen müssen? Wenn Sie reguläre Ausdrücke lieben, werden Sie sie verwenden. Aber ist es nicht einfacher/schneller/lesbarer, zwei Suchanfragen nacheinander zu verwenden? In den meisten Sprachen erzielen Sie wahrscheinlich eine bessere Leistung und machen Ihren Code besser lesbar.

Zum Beispiel ist der Beispielcode in Ingos Antwort ein gutes Beispiel, wenn Sie keine regulären Ausdrücke verwenden dürfen. Suchen Sie einfach nach foo und dann nach bar.

  • Beim Parsen von menschlichem Schreiben.

Ein gutes Beispiel ist ein Obszönitätsfilter. Es ist nicht nur eine schlechte Idee im Allgemeinen, 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 echte Obszönität zu bemerken, wird Ihr regulärer Ausdruck ihre Zeit damit verbringen, andere Benutzer zu verletzen.

  • Bei der Validierung einiger Datentypen.

Überprüfen Sie beispielsweise eine E-Mail-Adresse nicht durch einen regulären Ausdruck. In den meisten Fällen machen Sie es falsch. In seltenen Fällen machen Sie es richtig nd beenden mit einem Codierungshorror mit einer Länge von 6 343 Zeichen .

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.

  • Wann wird Ihr Code gelesen? Und dann immer wieder von verschiedenen Entwicklern lesen.

Im Ernst, wenn ich Ihren Code nehme und ihn überprüfen oder ändern muss, möchte ich keine Woche damit verbringen, zu versuchen, eine zwanzig Zeilen lange Zeichenfolge mit vielen Symbolen zu verstehen.

60

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 Buggy-Code).

18
Matteo

Beim Stackoverflow werden häufig Leute nach regulären Ausdrücken gefragt, die herausfinden, ob eine bestimmte Zeichenfolge nicht dies oder jenes enthält. Dies ist meiner Meinung nach die Umkehrung des Zwecks des regulären Ausdrucks. Selbst wenn es eine Lösung gibt (die negative Lookbehind-Behauptungen oder ähnliches verwendet), ist es oft viel besser, den regulären Ausdruck für das zu verwenden, wofür er gemacht wurde, und den negativen Fall mit Programmlogik zu behandeln.

Beispiel:

# bad
if (/complicated regex that assures the string does NOT conatin foo|bar/) {
    # do something
}

# appropriate
if (/foo|bar/) {
    # error handling
} else {
    # do something
}
12
Ingo

Zwei Fälle:

Wenn es einen einfacheren Weg gibt

  • 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 keinen eigenen regulären Ausdruck.

  • Wenn eine Bibliothek zum Ausführen einer komplexen Zeichenfolgenmanipulation verfügbar ist, verwenden Sie diese, anstatt Ihren eigenen regulären Ausdruck zu schreiben.

Wenn reguläre Ausdrücke nicht leistungsfähig genug sind

  • Wenn Sie einen Parser benötigen, verwenden Sie einen Parser.
5
Kramii

Reguläre Ausdrücke können rekursive Strukturen nicht identifizieren. Dies ist die grundlegende Einschränkung.

Nehmen Sie JSON - es ist ein ziemlich einfaches Format, aber da ein Objekt andere Objekte als Elementwerte enthalten kann (beliebig 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 erlauben es dem Muster nicht, sich auf sich selbst zu beziehen. Sie können nicht sagen: An dieser Stelle in der Syntax stimmen Sie wieder mit dem gesamten Muster überein. Anders ausgedrückt, reguläre Ausdrücke stimmen nur linear überein. Sie enthalten keinen Stapel, mit dem sie verfolgen können, wie tief ein verschachteltes Muster ist.

Beachten Sie, dass es nichts damit zu tun hat, wie komplex oder kompliziert 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 ziemlich komplexe Sprache, enthält jedoch keine rekursiven Strukturen und kann daher mit einem regulären Ausdruck analysiert werden. (Obwohl dies für CSS3 aufgrund von CSS-Ausdrücken mit rekursiver Syntax nicht gilt.)

Es liegt also nicht daran, dass es hässlich oder komplex oder fehleranfällig ist, HTML nur mit Regex zu analysieren. Es ist so, dass es einfach nicht möglich ist.

Wenn Sie ein Format analysieren müssen, das rekursive Strukturen enthält, müssen Sie die Verwendung regulärer Ausdrücke zumindest durch einen Stapel ergänzen, um die Ebene der rekursiven 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 wie dieses in separate Phasen unterteilt. Die 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. aufzuteilen. Das Parsen ist die nächste Phase, in der diese Token in eine hierarchische Struktur, einen Syntaxbaum, analysiert werden.

Wenn Sie also hören, dass HTML oder C # nicht durch reguläre Ausdrücke 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 einfach nicht mit nur regulären Ausdrücken und ohne Hilfecode analysieren.

0
JacquesB