2015-05-26 4 views
6

ich diese Zeichenfolge haben (man beachte die mehrzeiligen Syntax):Warum passt diese Regex auch Wörter innerhalb einer nicht einfangenden Gruppe?

var str = ` Number One: Get this 
    Number Two: And this`; 

Und ich möchte einen regulären Ausdruck, die (mit match) zurückgibt:

[str, 'Get this', 'And this'] 

Also habe ich versucht str.match(/Number (?:One|Two): (.*)/g);, aber das ist zurück:

["Number One: Get this", "Number Two: And this"] 

Vor jedem "Number" Wort können Leerstellen/Zeilenumbrüche vorhanden sein.

Warum gibt es nicht nur zurück, was innerhalb der einfangenden Gruppe ist? Mache ich etwas falsch? Und wie kann ich das gewünschte Ergebnis erzielen?

Antwort

4

Per the MDN documentation for String.match:

Wenn der reguläre Ausdruck die g-Flag enthält, gibt die Methode ein Array alle angepassten Substrings enthält anstatt Match-Objekte. Erfasste Gruppen werden nicht zurückgegeben. Wenn keine Übereinstimmungen vorhanden sind, gibt die Methode null zurück.

(Schwerpunkt meins).

Also, was Sie wollen, ist nicht möglich.

Die gleiche Seite ergänzt:

  • , wenn Sie Capture-Gruppen erhalten möchten und die globale Flag gesetzt ist,   Sie brauchen RegExp.exec() stattdessen zu verwenden.

also, wenn Sie sich mit match geben bereit sind, können Sie Ihre eigene Funktion schreiben, die immer wieder die Regex gilt, erhält die aufgenommenen Teil, und baut ein Array.


Oder für Ihren speziellen Fall, Sie so etwas schreiben könnte:

var these = str.split(/(?:^|\n)\s*Number (?:One|Two): /); 
these[0] = str; 
+0

In Ordnung, danke. Weißt du, ob das bei allen Regex-Engines gleich ist? Ich meine, wenn das daran liegt, wie Regex im Allgemeinen funktioniert. – Jacob

+0

Ich denke, ich mache das (natürlich, 'arr' deklarierend):' str.split ('\ n') forEach (x => arr.push (x.match (/ Number (?: One | Two): (. *) /) [1])); ', Was denkst du? – Jacob

+0

Ah, habe das Update nicht gesehen, das funktioniert auch. Und die Lösung von @ guest271314 funktioniert ebenfalls, aber Sie haben erklärt, warum das nicht der Fall war, und das ist nett. Vielen Dank. Ich bin nicht wirklich an der ganzen Saite interessiert, ich habe es nur so in der Frage geschrieben, weil ich dachte, dass Match immer mit einfangenden Gruppen arbeitet. – Jacob

2

Versuchen in einem neuen

var str = " Number One: Get this\ 
 
    Number Two: And this"; 
 
    // `/\w+\s+\w+(?=\s|$)/g` match one or more alphanumeric characters , 
 
    // followed by one or more space characters , 
 
    // followed by one or more alphanumeric characters , 
 
    // if following space or end of input , set `g` flag 
 
    // return `res` array `["Get this", "And this"]` 
 
    var res = str.match(/\w+\s+\w+(?=\s|$)/g); 
 

 
    document.write(JSON.stringify(res));

+1

Danke. Das ist auch schön und noch schöner mit Pfeilfunktionen !: 'var res = str.match (/: \ s + \ w + \ s + \ w +/g) .map (v => v.replace (": "," ") "));' – Jacob

2

ersetzen und das Ergebnis String, so:

var str = ` Number One: Get this 
Number Two: And this`; 
var output = str.replace(/Number (?:One|Two): (.*)/g, "$1"); 
console.log(output); 

die Ausgänge:

Get this 
And this 

Wenn Sie das Spiel Array wollen wie Sie angefordert, können Sie dies versuchen:

var getMatch = function(string, split, regex) { 
    var match = string.replace(regex, "$1" + split); 
    match = match.split(split); 
    match = match.reverse(); 
    match.push(string); 
    match = match.reverse(); 
    match.pop(); 
    return match; 
} 

var str = ` Number One: Get this 
Number Two: And this`; 
var regex = /Number (?:One|Two): (.*)/g; 
var match = getMatch(str, "#!SPLIT!#", regex); 
console.log(match); 

, die das Array zeigt, wie gewünscht:

[ ' Number One: Get this\n Number Two: And this', 
' Get this', 
'\n And this' ] 

Wo geteilt (hier #!SPLIT!#) sollte eine eindeutige Zeichenfolge sein, die m zu teilen atches. Beachten Sie, dass dies nur für einzelne Gruppen funktioniert. Fügen Sie für mehrere Gruppen eine Variable hinzu, die die Anzahl der Gruppen angibt, und fügen Sie eine for-Schleife hinzu, die "$1 $2 $3 $4 ..." + split erstellt.

+0

Danke! Die ganze Saite ist für mich nicht so wichtig, ich habe sie nur darauf hingewiesen, weil ich dachte, dass Match funktioniert. In Ihrem ersten Beispiel könnte man auch folgendes machen: 'output.trim(). Split ('\ n');' um das Array zu bekommen, denke ich. – Jacob

+1

Ja, das wird auch in diesem Fall funktionieren, aber ich denke, es wird scheitern, wenn es eine Zeile ohne Übereinstimmung gibt. – ShellFish

+0

Ah ja, du hast Recht, es werden auch Nicht-Übereinstimmungen im Array enthalten sein. – Jacob

Verwandte Themen