2014-01-09 12 views
5

Ich habe einen regulären Ausdruck, die mehr oder weniger wie diese genutzt werden:Warum Javascript String Match enthält undefined

'(801) 555-1234'.match(/^(1[-. ]?)?\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/) 

Aus irgendeinem Grund diese gibt

["(801) 555-1234", undefined] 

Wenn ich die globale Flag auf den regulären Ausdruck hinzufügen (zB ...{4}$/g), der nicht definierten Wert fällt ab und ich bekomme

["(801) 555-1234"] 

ich würde es vorziehen, nicht die g-Flag i zu verwenden, f es ist nicht notwendig (was es mir scheint, ist es nicht, da die Regex mit^beginnt und mit $ endet).

P.S. Ignoriere die Qualität der Regex, um passende Telefonnummern zu finden. Es ist vielleicht nicht ideal, aber es ist von Code, den ich behalte. Meistens interessiert mich das^... $ und das Vorhandensein/Fehlen der Flagge und der undefinierte Wert.

Warum erscheint undefined und warum macht die Flagge den Unterschied?

Antwort

7

ist hier eine Gruppe:

/^(1[-. ]?)?

.match (ohne /g Flag) und .exec return Gruppen als Teil des Arrays. Wenn die Gruppe nicht übereinstimmt, wird ihr Wert auf undefined festgelegt.

das erste Element Get:

'(801) 555-1234'.match(/^(1[-. ]?)?\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/)[0] 

Wenn Sie wirklich, wirklich, wirklich das Einzelelement-Array aus irgendeinem Grund wollen, können Sie es nicht-Capturing machen:

/^(?:1[-. ]?)?

jedoch, an diesem Punkt haben Sie diesen regulären Ausdruck sowohl am Anfang als auch am Ende der Zeichenfolge verankert und extrahieren keine Informationen.In diesem Fall scheint es, wie Sie wirklich suchen RegExp.prototype.test:

var PHONE_NUMBER = /^(1[-. ]?)?\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/; 
var isValid = PHONE_NUMBER.test('(801) 555-1234'); 
+2

Ah! das macht jetzt total Sinn. Die Array-Elemente spiegeln alle einfangenden Gruppen wider (ob sie optional waren oder nicht). Da die erste Gruppe keine Übereinstimmung gefunden hat, ist der Wert dieser Übereinstimmung nicht definiert. Macht jetzt Sinn, wenn Sie es sagen. Beim Betrachten des MDN-Beispiels sehe ich, dass das Array sowohl Übereinstimmungen für die Regex als auch Übereinstimmungen mit einfangenden Gruppen enthält. Vielen Dank. – jinglesthula

3

Es ist, weil Ihre Regex mit dieser eingeklammerten Gruppe beginnt. Die undefined im Ergebnis bedeutet, dass nichts zu diesem Teil passt.

Wenn Sie das Suffix "g" hinzufügen, ändert sich das Verhalten des Regex-Codes ein wenig, daher ist der Rückgabewert unterschiedlich. Das Suffix "g" ("global") bewirkt, dass die Routine alle Übereinstimmungen der gesamten Regex zurückgibt; Die Gruppen werden in diesem Fall effektiv ignoriert. Zum Beispiel:

"hello world! nice day today!".match(/\w+/g) 

würde ein Array wie folgt zurück:

["hello", "world", "nice", "day", "today"] 
+0

Kennen Sie Details darüber, wie sich das Verhalten ändert? das wäre schön zu wissen, obwohl es nicht ganz entscheidend ist zu verstehen, woher das undefinierte kam (was du gut beantwortet hast) – jinglesthula

+0

@jinglesthula danke für die Frage - ich wollte zurückkommen und das hinzufügen, weil ich die Dokumentation überprüfen musste stelle sicher, dass ich mich richtig erinnere, aber ich habe es vergessen :) Ich werde gleich updaten. – Pointy

3

Sie haben einen aufgenommenen Unter-Pattern: (1[-. ]?)?

Es ist optional.

In diesem Fall besteht die Option darin, sie nicht zu finden.

So ist es undefiniert.

versuchen, ein nicht-Capturing Submuster verwendet: (?:1[-. ]?)?

1

in Ihre Regex (1[-. ]?)? zeigt

NODE      EXPLANATION 
-------------------------------------------------------------------------------- 
    (      group and capture to \1 (optional 
          (matching the most amount possible)): 
-------------------------------------------------------------------------------- 
    1      '1' 
-------------------------------------------------------------------------------- 
    [-. ]?     any character of: '-', '.', ' ' 
          (optional (matching the most amount 
          possible)) 
-------------------------------------------------------------------------------- 
)?      end of \1 (NOTE: because you are using a 
          quantifier on this capture, only the LAST 
          repetition of the captured pattern will be 
          stored in \1) 

enter image description here

Und Versuchen (?:1[-. ]?)?

NODE      EXPLANATION 
-------------------------------------------------------------------------------- 
    (?:      group, but do not capture (optional 
          (matching the most amount possible)): 
-------------------------------------------------------------------------------- 
    1      '1' 
-------------------------------------------------------------------------------- 
    [-. ]?     any character of: '-', '.', ' ' 
          (optional (matching the most amount 
          possible)) 
-------------------------------------------------------------------------------- 
)?      end of grouping 

enter image description here