2013-07-28 2 views
6

Ich habe versucht, dieses SpielWarum erzeugt String.match() keine erwarteten Ergebnisse, wenn ein globales Flag vorhanden ist?

'/links/51f5382e7b7993e335000015'.match(/^\/links\/([0-9a-f]{24})$/g) 

und bekam:

['/links/51f5382e7b7993e335000015'] 

während ich erwartet hatte:

['/links/51f5382e7b7993e335000015', '51f5382e7b7993e335000015'] 

ich hatte kein Glück, bis ich die globale Flagge entfernt, was ich tat, nicht denken würde Auswirkungen auf meine Ergebnisse!

Mit der globalen Flagge entfernt,

'/links/51f5382e7b7993e335000015'.match(/^\/links\/([0-9a-f]{24})$/) 

produziert:

[ '/links/51f5382e7b7993e335000015', 
    '51f5382e7b7993e335000015', 
    index: 0, 
    input: '/links/51f5382e7b7993e335000015' ] 

was cool ist, aber die Dokumentation zu lesen ich kann nicht herausfinden:

  • Warum der erste Formular hat nicht funktioniert
  • Warum die globale Flagge mit dergestörtpassende
  • Wie ohne die index und input Eigenschaften mein erwartetes Ergebnis erhalten

Auf JavaScript Regex and Submatches die Top-Antwort sagt:

Mit String der match() Funktion gibt nicht erfaßt Gruppen, wenn die Der globale Modifikator wird gesetzt, wie Sie herausgefunden haben. Jedoch

,

> 'fofoofooofoooo'.match(/f(o+)/g) 
["fo", "foo", "fooo", "foooo"] 

scheint gefangen Gruppen zu produzieren gut.

Vielen Dank.

+0

Ich bearbeitet die Frage, um das mögliche doppelte Problem zu adressieren. –

+1

Es ist ein Duplikat, aber +1 für "Ich habe es versucht ... ich habe ..., ich hatte erwartet ...". Ich wünschte, mehr Fragen wären so. – FakeRainBrigand

+0

Hah! Danke ... Ich werde auf der verlinkten Seite noch genauer hinschauen. –

Antwort

3

Von this msdn documentation für Spiel-Methode:

Wenn die globale Flagge (g) nicht gesetzt ist, Element Null des Arrays enthält das gesamte Spiel, während die Elemente 1 bis n irgendwelche submatches enthalten. Dieses Verhalten entspricht dem Verhalten der exec-Methode (Regulärer Ausdruck) (JavaScript), wenn das globale Flag nicht gesetzt ist. Wenn das globale Flag gesetzt ist, enthalten Elemente 0 bis n alle Übereinstimmungen, die aufgetreten sind.

Schwerpunkt meiner.

Also, in Ihrem ersten Fall:

'/links/51f5382e7b7993e335000015'.match(/^\/links\/([0-9a-f]{24})$/g) 

Da /g Modifikator gesetzt ist, wird es nur die kompletten Matches zurück, die aufgetreten sind, und nicht die submatches. Deshalb haben Sie gerade ein Array mit einem einzelnen Element. Da es für diese Regex nur 1 Übereinstimmung gibt.

2. Fall:

'/links/51f5382e7b7993e335000015'.match(/^\/links\/([0-9a-f]{24})$/) 

/g Schlüssel nicht gesetzt ist. So enthält das Array die vollständige Übereinstimmung bei 0th Index. Und weitere Elemente (1. Index) in der Anordnung sind Unterübereinstimmungen - in diesem Fall die erste Erfassungsgruppe.


Was Ihr letztes Beispiel:

'fofoofooofoooo'.match(/f(o+)/g) 

Wieder da /g Modifikator gesetzt ist, wird es alle Spiele aus der Zeichenfolge zurück, und nicht die submatches. Also, in der Zeichenfolge, f(o+) die Regex entspricht 4 mal:

fo - 1st complete match (sub-match 'o' in 1st captured group ignored) 
foo - 2nd complete match (sub-match 'oo' ignored) 
fooo - 3rd complete match (sub-match 'ooo' ignored) 
foooo - 4th complete match (sub-match 'oooo' ignored) 

Wenn Sie die letzte regex ohne /g Modifikator verwenden, würden Sie jedes submatch als separates Element gehen, dass das erste Spiel. Versuchen:

'fofoofooofoooo'.match(/f(o+)/) 

Sie erhalten wird:

["fo", "o"] // With index and input element of course. 

Ohne /g es hält nur nach dem ersten Spiel (fo) und gibt das gesamte Spiel und Unter Begegnungen.

+0

Vielen Dank für diesen Rohit! Wow, wirklich zu schätzen diese Antwort. –

+0

@dimadima Gern geschehen :) –

+0

Rohit: '' foofooofoooo'.match (/ f (o +) /) 'erzeugt' ['fo', 'o', Index: 0, Eingabe: 'fofooooooooo'] '. Ich glaube, das liegt daran, dass es kein Backtracking gibt. –

1

Wenn das Flag g nicht angegeben ist, werden die gleichen Ergebnisse zurückgegeben wie unter RegExp.exec(), wodurch ein Array mit Elementen zum Erfassen von Klammern zurückgegeben wird.

Wenn das Flag g angegeben ist, wird ein Array mit allen Übereinstimmungen zurückgegeben.

Diese Beschreibung ist mit den Beispielen in der Frage konsistent, aber Ihre beiden Beispiele sind eine Art von Äpfeln mit Orangen:

  • Ihr „Links“ Regex paßt die gesamte Eingabezeichenfolge einmal, möglicherweise mit einer erfassten Gruppe je auf der Flagge.
  • Ihre /f(o+)/g Regex stimmt mit mehreren Teilstrings im Eingang überein.
+0

Danke für diese Antwort und deine Klarstellung meines Beispiels –

Verwandte Themen