Javascript - MultiLine RegExp: lastIndex auf Newlines fest?

8

Irgendein Kontext

Aus Javascript: Das endgültige Handbuch :

  

Wenn regexp ein globaler regulärer Ausdruck ist, verhält sich exec() jedoch etwas komplexer. Es beginnt mit der Suche nach string an der Zeichenposition, die von lastIndex preperty von regexp angegeben wurde. Wenn eine Übereinstimmung gefunden wird, wird lastIndex auf die Position des ersten Zeichens nach der Übereinstimmung gesetzt.

Ich denke, jeder, der regelmäßig mit Javascript RegExps arbeitet, wird diese Passage erkennen. Allerdings habe ich bei dieser Methode ein seltsames Verhalten festgestellt.

Das Problem

Betrachten Sie den folgenden Code:

%Vor%

Die RegExp scheint in der zweiten Zeile stecken zu bleiben und erhöht nicht die Eigenschaft lastIndex . Dies scheint dem Rhino-Buch zu widersprechen. Wenn ich es selbst wie folgt setze, fährt es fort und gibt schließlich wie erwartet null zurück, aber es scheint, als müsste ich nicht.

%Vor%

Fazit

Offensichtlich kann ich die Eigenschaft lastIndex jedes Mal erhöhen, wenn die Übereinstimmung die leere Zeichenfolge ist. Ich möchte jedoch wissen, warum der inquisitive Typ nicht durch die Methode exec inkrementiert wird. Warum nicht?

Notizen

Ich habe dieses Verhalten in Chrome und Firefox beobachtet. Es scheint nur zu passieren, wenn benachbarte Zeilenumbrüche vorhanden sind.

[Bearbeiten]

Tomalak sagt unten, dass das Ändern des Musters in /^(.+)$/gm dazu führt, dass der Ausdruck nicht stecken bleibt, sondern das Leerzeichen Zeile wird ignoriert. Kann dies geändert werden, um immer noch der Linie zu entsprechen? Danke für die Antwort Tomalak !

[Bearbeiten]

Das folgende Muster zu verwenden und Gruppe 1 zu verwenden funktioniert für alle Zeichenfolgen, die ich mir vorstellen kann. Danke nochmal an Tomalak .

%Vor%

[Bearbeiten]

Das vorherige Muster gibt die Leerzeile zurück. Wenn Sie jedoch die leeren Zeilen nicht interessieren, Tomalak gibt die folgende Lösung, die ich für sauberer halte.

%Vor%

[Bearbeiten]

Die beiden vorherigen Lösungen bleiben bei Zeilenumbrüchen hängen, daher müssen Sie sie entweder entfernen oder lastIndex manuell erhöhen.

[Bearbeiten]

Ich habe einen großartigen Artikel gefunden, der die Cross-Browser-Probleme mit lastIndex über Flaggant Badassery beschreibt. Neben dem großartigen Blog-Namen gab mir der Artikel ein tiefergehendes Verständnis des Themas und eine gute Cross-Browser-Lösung. Die Lösung ist wie folgt:

%Vor%     
brad 23.05.2017, 10:27
quelle

2 Antworten

7

Das Problem ist, dass der Punkt in

%Vor%

stimmt nicht mit neuen Zeilenzeichen überein, aber mit Ihrem "m" -Schalter machen Sie "^" und "$" anchor zu neuen Zeilenzeichen. Das heißt, das "Nichts" zwischen "\n" und "\n" kann erfolgreich mit "(.*)" verglichen werden.

Da diese Übereinstimmung eine Breite von null hat, kann die lastIndex -Eigenschaft nicht vorrücken. Probieren Sie:

%Vor%

BEARBEITEN: Um auch die Leerzeilen anzupassen, tun Sie dies:

%Vor%

oder

%Vor%

... und gehen Sie einfach zur Match-Gruppe 1.

    
Tomalak 19.12.2008, 15:13
quelle
2

Das Problem mit lastIndex ist, dass eine JavaScript-Implementierung, die dem Standard auf den Buchstaben folgt, den Offset des nächsten Zeichens nach der Übereinstimmung festlegt. Für reguläre Ausdrücke wie Ihre, die Übereinstimmungen mit der Länge Null zulassen, bleibt exec () daher in einer Endlosschleife stecken, wenn eine Übereinstimmung mit der Länge Null gefunden wird. Der nächste Match-Versuch beginnt an der gleichen Position, an der die gleiche Null-Längen-Übereinstimmung gefunden wird.

Traditionell gehen Regex-Engines damit um, indem sie ein Zeichen überspringen, wenn eine Null-Länge-Übereinstimmung gefunden wird. Übrigens tut Internet Explorer dies auch.

Ich habe in der Vergangenheit ausführlich darüber gebloggt: Watch Out für Zero-Length-Matches

    
Jan Goyvaerts 25.12.2008 13:44
quelle

Tags und Links