Reguläre Ausdrücke lernen [geschlossen]

166

Ich verstehe reguläre Ausdrücke nicht wirklich. Können Sie sie mir auf leicht verständliche Weise erklären? Wenn es Online-Tools oder Bücher gibt, können Sie diese auch verlinken?

Teifion
quelle

Antworten:

789

Der wichtigste Teil sind die Konzepte. Sobald Sie verstanden haben, wie die Bausteine ​​funktionieren, betragen die Unterschiede in der Syntax kaum mehr als milde Dialekte. Eine Ebene über der Syntax Ihrer Engine für reguläre Ausdrücke ist die Syntax der von Ihnen verwendeten Programmiersprache. Sprachen wie Perl beseitigen den größten Teil dieser Komplikation, aber Sie müssen andere Überlegungen berücksichtigen, wenn Sie reguläre Ausdrücke in einem C-Programm verwenden.

Wenn Sie reguläre Ausdrücke als Bausteine ​​betrachten, die Sie nach Belieben mischen und anpassen können, lernen Sie, wie Sie Ihre eigenen Muster schreiben und debuggen, aber auch wie Sie von anderen geschriebene Muster verstehen.

Fangen Sie einfach an

Konzeptionell sind die einfachsten regulären Ausdrücke wörtliche Zeichen. Das Muster Nentspricht dem Zeichen 'N'.

Reguläre Ausdrücke nebeneinander stimmen mit Sequenzen überein. Zum Beispiel das MusterNick stimmt mit der Sequenz 'N' überein, gefolgt von 'i', gefolgt von 'c', gefolgt von 'k'.

Wenn Sie jemals unter grepUnix verwendet haben - auch wenn Sie nur nach normal aussehenden Zeichenfolgen suchen -, haben Sie bereits reguläre Ausdrücke verwendet! (Das rein grepbezieht sich auf reguläre Ausdrücke.)

Bestellung aus dem Menü

Wenn Sie nur ein wenig Komplexität hinzufügen, können Sie entweder 'Nick' oder 'Nick' mit dem Muster abgleichen [Nn]ick. Der Teil in eckigen Klammern ist eine Zeichenklasse , dh er entspricht genau einem der eingeschlossenen Zeichen. Sie können auch Bereiche in Zeichenklassen verwenden, sodass [a-c]entweder 'a' oder 'b' oder 'c' übereinstimmen.

Das Muster .ist etwas Besonderes: Anstatt nur einem wörtlichen Punkt zu entsprechen, stimmt es mit jedem Zeichen überein . Es ist konzeptionell dasselbe wie die wirklich große Charakterklasse [-.?+%$A-Za-z0-9...].

Stellen Sie sich Charakterklassen als Menüs vor: Wählen Sie nur eines aus.

Hilfreiche Verknüpfungen

Durch .die Verwendung können Sie viel Tipparbeit sparen, und es gibt andere Verknüpfungen für häufig verwendete Muster. Angenommen, Sie möchten einer Ziffer entsprechen: Eine Möglichkeit, dies zu schreiben, ist [0-9]. Ziffern sind ein häufiges Übereinstimmungsziel, daher können Sie stattdessen die Verknüpfung verwenden \d. Andere sind \s(Leerzeichen) und \w(Wortzeichen: alphanumerisch oder Unterstrich).

Die Großbuchstabenvarianten sind ihre Ergänzungen und passen daher beispielsweise zu \Sallen Nicht- Leerzeichen.

Einmal ist nicht genug

Von dort aus können Sie Teile Ihres Musters mit Quantifizierern wiederholen . Beispielsweise ab?cstimmt das Muster mit 'abc' oder 'ac' ?überein , da der Quantifizierer das zu ändernde Untermuster optional macht. Andere Quantifizierer sind

  • * (null oder mehrmals)
  • + (einmal oder mehrmals)
  • {n}(genau n mal)
  • {n,}(mindestens n mal)
  • {n,m}(mindestens n- mal, aber nicht mehr als m- mal)

Wenn Sie einige dieser Blöcke zusammenfügen, [Nn]*ickstimmt das Muster mit allen überein

  • ick
  • Nick
  • Nick
  • Nnick
  • nNick
  • nnick
  • (und so weiter)

Das erste Spiel zeigt eine wichtige Lektion: *Immer erfolgreich! Jedes Muster kann nullmal übereinstimmen.

Einige andere nützliche Beispiele:

  • [0-9]+ (und sein Äquivalent \d+ ) stimmt mit einer nicht negativen Ganzzahl überein
  • \d{4}-\d{2}-\d{2} Übereinstimmungsdaten formatiert wie 2019-01-01

Gruppierung

Ein Quantifizierer ändert das Muster unmittelbar links davon. Sie können erwarten 0abc+0, dass '0abc0', '0abcabc0' usw. übereinstimmen, aber das Muster unmittelbar links vom Plus-Quantifizierer ist c. Dies bedeutet, dass 0abc+0Übereinstimmungen mit '0abc0', '0abcc0', '0abccc0' usw. übereinstimmen.

Verwenden Sie, um eine oder mehrere Sequenzen von 'abc' mit Nullen an den Enden abzugleichen 0(abc)+0. Die Klammern bezeichnen ein Untermuster, das als Einheit quantifiziert werden kann. Es ist auch üblich, dass Engines für reguläre Ausdrücke den Teil des Eingabetextes speichern oder "erfassen", der einer Gruppe in Klammern entspricht. Das Extrahieren von Bits auf diese Weise ist viel flexibler und weniger fehleranfällig als das Zählen von Indizes und substr.

Wechsel

Früher haben wir einen Weg gesehen, entweder 'Nick' oder 'Nick' zu finden. Ein anderer ist im Wechsel wie in Nick|nick. Denken Sie daran, dass der Wechsel alles zu seiner Linken und alles zu seiner Rechten umfasst. Verwenden Sie Klammern , die Gruppierung den Umfang zu begrenzen |, zum Beispiel , (Nick|nick).

In einem anderen Beispiel könnten Sie äquivalent schreiben [a-c]als a|b|c, aber dies ist wahrscheinlich nicht optimal, da viele Implementierungen davon ausgehen, dass Alternativen Längen größer als 1 haben.

Flucht

Obwohl einige Zeichen mit sich selbst übereinstimmen, haben andere eine besondere Bedeutung. Das Muster \d+stimmt nicht mit dem Backslash überein, gefolgt von Kleinbuchstaben D, gefolgt von einem Pluszeichen: Um dies zu erhalten, würden wir verwenden \\d\+. Ein Backslash entfernt die besondere Bedeutung des folgenden Zeichens.

Gier

Quantifizierer für reguläre Ausdrücke sind gierig. Dies bedeutet, dass sie so viel Text wie möglich abgleichen, während das gesamte Muster erfolgreich übereinstimmt.

Angenommen, die Eingabe lautet

"Hallo", sagte sie, "wie geht es dir?"

Sie können davon ausgehen ".+", dass nur "Hallo" übereinstimmt, und werden dann überrascht sein, wenn Sie sehen, dass es von "Hallo" bis "Sie?" Übereinstimmt.

Fügen Sie ?dem Quantifizierer ein Extra hinzu , um von gierig zu dem zu wechseln, was Sie für vorsichtig halten . Jetzt verstehen Sie, wie \((.+?)\)das Beispiel aus Ihrer Frage funktioniert. Es entspricht der Reihenfolge einer wörtlichen linken Klammer, gefolgt von einem oder mehreren Zeichen, und wird durch eine rechte Klammer abgeschlossen.

Wenn Ihre Eingabe '(123) (456)' ist, ist die erste Aufnahme '123'. Nicht gierige Quantifizierer möchten, dass der Rest des Musters so schnell wie möglich mit dem Abgleich beginnt.

(In Bezug auf Ihre Verwirrung kenne ich keinen Dialekt mit regulären Ausdrücken, in dem ((.+?))das Gleiche der Fall wäre. Ich vermute, dass irgendwo auf dem Weg etwas bei der Übertragung verloren gegangen ist.)

Anker

Verwenden Sie das spezielle Muster ^, um nur am Anfang Ihrer Eingabe und $nur am Ende übereinzustimmen. Es ist eine nützliche Technik, mit Ihren Mustern "Buchstützen" zu machen, in denen Sie sagen: "Ich weiß, was vorne und hinten ist, aber geben Sie mir alles dazwischen".

Angenommen, Sie möchten Kommentare des Formulars abgleichen

-- This is a comment --

du würdest schreiben ^--\s+(.+)\s+--$.

Bau dein eigenes

Reguläre Ausdrücke sind rekursiv. Nachdem Sie diese Grundregeln verstanden haben, können Sie sie beliebig kombinieren.

Tools zum Schreiben und Debuggen von Regexen:

Bücher

Kostenlose Ressourcen

Fußnote

†: Die obige Aussage, die .mit jedem Charakter übereinstimmt, ist eine Vereinfachung für pädagogische Zwecke, die nicht unbedingt wahr ist. Punkt entspricht jedem Zeichen außer Zeilenumbruch, "\n"aber in der Praxis erwarten Sie selten ein Muster .+, das eine Zeilenumbruchgrenze überschreitet. Perl-Regexes haben einen /sSchalter und Java Pattern.DOTALL, um beispielsweise .jedem Zeichen eine Übereinstimmung zu geben. Für Sprachen, die keine solche Funktion haben, können Sie so etwas wie [\s\S]"jedes Leerzeichen oder jedes Nicht-Leerzeichen" verwenden, mit anderen Worten alles.

Greg Bacon
quelle
14
Sie können auch die Trial-and-Error-Methode verwenden und dann kann das Befolgen des
Juraj.Lorinc
2
Es wäre erwähnenswert, dass es, obwohl es sich um ein ähnliches Muster a{,m}handelt, zumindest in Javascript, Perl und Python keine Sache ist.
Fund Monica Klage
2
Es wäre sehr erwähnenswert, dass es verschiedene Arten von Engines für reguläre Ausdrücke gibt, die alle unterschiedliche Funktionssätze und syntaktische Regeln haben.
hek2mgl
1
hackr.io/tutorials/learn-regular-expressions-regex ist ein großartiger Ort, um die besten Online-Regex-Tutorials zu finden. Alle Tutorials hier werden von der Programmier-Community eingereicht und empfohlen (wie SO bewertet).
Saurabh Hooda
2
Schätzen Sie Ihre Bemühungen, alles hier auf den Punkt zu bringen.
Saurabh Tiwari