Wie greifen Sie in einem regulären JavaScript-Ausdruck auf die übereinstimmenden Gruppen zu?


1368

Ich möchte einen Teil einer Zeichenfolge mit einem regulären Ausdruck abgleichen und dann auf diesen Teilstring in Klammern zugreifen:

var myString = "something format_abc"; // I want "abc"

var arr = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString);

console.log(arr);     // Prints: [" format_abc", "abc"] .. so far so good.
console.log(arr[1]);  // Prints: undefined  (???)
console.log(arr[0]);  // Prints: format_undefined (!!!)

Was mache ich falsch?


Ich habe festgestellt, dass mit dem obigen Code für reguläre Ausdrücke nichts falsch ist: Die eigentliche Zeichenfolge, gegen die ich getestet habe, war folgende:

"date format_%A"

Die Meldung, dass "% A" undefiniert ist, scheint ein sehr seltsames Verhalten zu sein, steht jedoch nicht in direktem Zusammenhang mit dieser Frage. Daher habe ich eine neue geöffnet. Warum gibt eine übereinstimmende Teilzeichenfolge in JavaScript "undefiniert" zurück? .


Das Problem war, dass console.logdie Parameter wie eine printfAnweisung verwendet werden. Da die von mir protokollierte Zeichenfolge ( "%A") einen speziellen Wert hatte, wurde versucht, den Wert des nächsten Parameters zu ermitteln.

Antworten:


1674

Sie können auf folgende Erfassungsgruppen zugreifen:

var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abc

Und wenn es mehrere Übereinstimmungen gibt, können Sie diese durchlaufen:

var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
match = myRegexp.exec(myString);
while (match != null) {
  // matched text: match[0]
  // match start: match.index
  // capturing group n: match[n]
  console.log(match[0])
  match = myRegexp.exec(myString);
}

Bearbeiten: 2019-09-10

Wie Sie sehen können, war die Art und Weise, mehrere Übereinstimmungen zu durchlaufen, nicht sehr intuitiv. Dies führte zum Vorschlag der String.prototype.matchAllMethode. Diese neue Methode wird voraussichtlich in der ECMAScript 2020-Spezifikation enthalten sein . Es gibt uns eine saubere API und löst mehrere Probleme. Es wurde gestartet, um auf gängigen Browsern und JS-Engines wie Chrome 73+ / Node 12+ und Firefox 67+ zu landen .

Die Methode gibt einen Iterator zurück und wird wie folgt verwendet:

const string = "something format_abc";
const regexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
const matches = string.matchAll(regexp);
    
for (const match of matches) {
  console.log(match);
  console.log(match.index)
}

Da es einen Iterator zurückgibt, können wir sagen, dass er faul ist. Dies ist nützlich, wenn besonders viele Erfassungsgruppen oder sehr große Zeichenfolgen erfasst werden. Bei Bedarf kann das Ergebnis jedoch mithilfe der Spread-Syntax oder der folgenden Array.fromMethode einfach in ein Array umgewandelt werden :

function getFirstGroup(regexp, str) {
  const array = [...str.matchAll(regexp)];
  return array.map(m => m[1]);
}

// or:
function getFirstGroup(regexp, str) {
  return Array.from(str.matchAll(regexp), m => m[1]);
}

Während dieser Vorschlag mehr Unterstützung findet, können Sie in der Zwischenzeit das offizielle Shim-Paket verwenden .

Auch die internen Abläufe der Methode sind einfach. Eine äquivalente Implementierung unter Verwendung einer Generatorfunktion wäre wie folgt:

function* matchAll(str, regexp) {
  const flags = regexp.global ? regexp.flags : regexp.flags + "g";
  const re = new RegExp(regexp, flags);
  let match;
  while (match = re.exec(str)) {
    yield match;
  }
}

Eine Kopie des ursprünglichen regulären Ausdrucks wird erstellt. Dies dient dazu, Nebenwirkungen aufgrund der Mutation der lastIndexEigenschaft beim Durchlaufen der Mehrfachübereinstimmungen zu vermeiden .

Außerdem müssen wir sicherstellen, dass der reguläre Ausdruck das globale Flag hat, um eine Endlosschleife zu vermeiden.

Ich bin auch froh zu sehen, dass auch diese StackOverflow-Frage in den Diskussionen des Vorschlags erwähnt wurde .


114
+1 Bitte beachten Sie, dass Sie im zweiten Beispiel das RegExp-Objekt verwenden sollten (nicht nur "/ myregexp /"), da es den lastIndex-Wert im Objekt behält. Ohne das Regexp-Objekt zu verwenden, wird es unendlich iterieren
ianaz

7
@ianaz: Ich glaube nicht, dass es wahr ist? http://jsfiddle.net/weEg9/ scheint zumindest auf Chrome zu funktionieren.
Spinningarrow

16
Warum das oben genannte anstelle von : var match = myString.match(myRegexp); // alert(match[1])?
JohnAllen

29
Es ist keine explizite "neue RegExp" erforderlich, jedoch tritt die Endlosschleife auf, sofern nicht / g angegeben ist
George C

4
Eine andere Möglichkeit, nicht in eine Endlosschleife zu geraten, besteht darin, die Zeichenfolge explizit zu aktualisieren, z. B.string = string.substring(match.index + match[0].length)
Olga,

186

Hier ist eine Methode, mit der Sie die n- te Erfassungsgruppe für jedes Spiel ermitteln können:

function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
    matches.push(match[index]);
  }
  return matches;
}


// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;

// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);

// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);


12
Dies ist eine weitaus bessere Antwort als die anderen, da die Iteration über alle Übereinstimmungen korrekt angezeigt wird, anstatt nur eine zu erhalten.
Rob Evans

13
mnn ist richtig. Dies erzeugt eine Endlosschleife, wenn das 'g'-Flag nicht vorhanden ist. Seien Sie mit dieser Funktion sehr vorsichtig.
Druska

4
Ich habe dies verbessert, um es Python's re.findall () ähnlich zu machen. Es gruppiert alle Übereinstimmungen in einem Array von Arrays. Es behebt auch das Endlosschleifenproblem des globalen Modifikators. jsfiddle.net/ravishi/MbwpV
Ravishi

5
@MichaelMikowski Jetzt hast du gerade deine Endlosschleife versteckt, aber dein Code läuft langsam. Ich würde argumentieren, dass es besser ist, Code schlecht zu brechen, damit Sie ihn in der Entwicklung erkennen. Es ist schlampig, einige bs maximale Iterationen einzubrechen. Das Ausblenden von Problemen anstelle der Behebung ihrer Grundursache ist nicht die Antwort.
Wallacer

4
@MichaelMikowski, das ist nicht wesentlich langsamer, wenn Sie das Ausführungslimit nicht erreichen. Wenn Sie sind, ist es deutlich langsamer. Ich sage nicht, dass Ihr Code nicht funktioniert, ich sage, dass er in der Praxis mehr Schaden als Nutzen verursachen wird. Menschen, die in einer Entwicklungsumgebung arbeiten, werden feststellen, dass der Code ohne Last einwandfrei funktioniert, obwohl 10.000 unnötige Ausführungen eines Codeabschnitts durchgeführt wurden. Dann werden sie es in eine Produktionsumgebung übertragen und sich fragen, warum ihre App unter Last ausfällt. Nach meiner Erfahrung ist es besser, wenn die Dinge auf offensichtliche Weise und früher im Entwicklungszyklus brechen.
Wallacer

58

var myString = "something format_abc";
var arr = myString.match(/\bformat_(.*?)\b/);
console.log(arr[0] + " " + arr[1]);

Das \bist nicht genau das Gleiche. (Es funktioniert weiter --format_foo/, funktioniert aber nicht weiter format_a_b) Aber ich wollte eine Alternative zu Ihrem Ausdruck zeigen, die in Ordnung ist. Natürlich ist der matchAnruf das Wichtigste.


2
Es ist genau umgekehrt. '\ b' begrenzt Wörter. word = '\ w' = [a-zA-Z0-9_]. "format_a_b" ist ein Wort.
BF

1
@BFHonestly, ich format_a_bhabe vor 6 Jahren nachträglich "funktioniert nicht " hinzugefügt , und ich erinnere mich nicht, was ich dort gemeint habe ... :-) Ich nehme an, es bedeutete "funktioniert nicht anur zum Erfassen ", dh. der erste alphabetische Teil danach format_.
PhiLho

1
Ich wollte sagen, dass \ b (- format_foo /} \ b nicht "--format_foo /" zurückgibt, weil "-" und "/" keine \ Wortzeichen sind. Aber \ b (format_a_b) \ b gibt "format_a_b" zurück ". Richtig? Ich beziehe mich auf Ihre Textaussage in runden Klammern. (Hat nicht abgestimmt!)
BF

31

In Bezug auf die obigen Beispiele für Klammern mit mehreren Übereinstimmungen habe ich hier nach einer Antwort gesucht, nachdem ich nicht das bekommen hatte, was ich wollte:

var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);

Nachdem ich mir die leicht verschlungenen Funktionsaufrufe mit while und .push () oben angesehen hatte, wurde mir klar, dass das Problem stattdessen sehr elegant mit mystring.replace () gelöst werden kann (das Ersetzen ist NICHT der Punkt und wird noch nicht einmal durchgeführt Die integrierte rekursive Funktionsaufrufoption CLEAN für den zweiten Parameter lautet!):

var yourstring = 'something format_abc something format_def something format_ghi';

var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.push(p1); } );

Danach glaube ich nicht, dass ich .match () jemals wieder für kaum etwas verwenden werde.


26

Zu guter Letzt habe ich eine Codezeile gefunden, die für mich gut funktioniert hat (JS ES6):

let reg = /#([\S]+)/igm; // Get hashtags.
let string = 'mi alegría es total! ✌🙌\n#fiestasdefindeaño #PadreHijo #buenosmomentos #france #paris';

let matches = (string.match(reg) || []).map(e => e.replace(reg, '$1'));
console.log(matches);

Dies wird zurückkehren:

['fiestasdefindeaño', 'PadreHijo', 'buenosmomentos', 'france', 'paris']

1
BOOM! Das ist hier die eleganteste Lösung. Ich fand das besser als den vollständigen replaceAnsatz von Alexz, weil dieser weniger vorausschauend und eleganter für mehrere Ergebnisse ist. Gute Arbeit, Sebastien H.
Cody

Das funktioniert so gut, dass es definitiv in meine Utensilien geht :)
Cody

1
@Cody haha ​​danke Mann!
Sebastien H.

19

In dieser Antwort verwendete Terminologie:

  • Übereinstimmung gibt das Ergebnis der Ausführung Ihres RegEx-Musters für Ihre Zeichenfolge wie folgt an : someString.match(regexPattern).
  • Übereinstimmende Muster geben alle übereinstimmenden Teile der Eingabezeichenfolge an, die sich alle im Übereinstimmungsarray befinden . Dies sind alles Instanzen Ihres Musters innerhalb der Eingabezeichenfolge.
  • Übereinstimmende Gruppen geben alle zu fangenden Gruppen an, die im RegEx-Muster definiert sind. (Die Muster in Klammern wie folgt: /format_(.*?)/gWo (.*?)wäre eine übereinstimmende Gruppe?) Diese befinden sich in übereinstimmenden Mustern .

Beschreibung

Um Zugriff auf die übereinstimmenden Gruppen zu erhalten , benötigen Sie in jedem der übereinstimmenden Muster eine Funktion oder ähnliches, um die Übereinstimmung zu durchlaufen . Es gibt eine Reihe von Möglichkeiten, wie Sie dies tun können, wie viele der anderen Antworten zeigen. Die meisten anderen Antworten verwenden eine while-Schleife, um alle übereinstimmenden Muster zu durchlaufen , aber ich denke, wir alle kennen die potenziellen Gefahren bei diesem Ansatz. Es ist notwendig, mit einem new RegExp()statt nur dem Muster selbst abzugleichen, das nur in einem Kommentar erwähnt wurde. Dies liegt daran, dass sich die .exec()Methode ähnlich wie eine Generatorfunktion verhält - sie stoppt jedes Mal , wenn eine Übereinstimmung vorliegt, behält jedoch ihre Funktion bei .lastIndex, um beim nächsten .exec()Aufruf fortzufahren .

Codebeispiele

Unten sehen Sie ein Beispiel für eine Funktion, searchStringdie eines Arrayaller übereinstimmenden Muster zurückgibt , wobei jedes matchein Arraymit allen enthaltenen übereinstimmenden Gruppen ist . Anstatt eine while-Schleife zu verwenden, habe ich Beispiele bereitgestellt, die sowohl die Array.prototype.map()Funktion als auch eine performantere Methode verwenden - mithilfe einer einfachen forSchleife.

Prägnante Versionen (weniger Code, mehr syntaktischer Zucker)

Diese sind weniger performant, da sie im Grunde eine forEach-schleife anstelle der schnelleren for-schleife implementieren.

// Concise ES6/ES2015 syntax
const searchString = 
    (string, pattern) => 
        string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match => 
            new RegExp(pattern.source, pattern.flags)
            .exec(match));

// Or if you will, with ES5 syntax
function searchString(string, pattern) {
    return string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match =>
            new RegExp(pattern.source, pattern.flags)
            .exec(match));
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

Performante Versionen (mehr Code, weniger syntaktischer Zucker)

// Performant ES6/ES2015 syntax
const searchString = (string, pattern) => {
    let result = [];

    const matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (let i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
};

// Same thing, but with ES5 syntax
function searchString(string, pattern) {
    var result = [];

    var matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (var i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

Ich habe diese Alternativen noch nicht mit den zuvor in den anderen Antworten erwähnten verglichen, aber ich bezweifle, dass dieser Ansatz weniger leistungsfähig und weniger ausfallsicher ist als die anderen.


19

String#matchAll(siehe Entwurf der Stufe 3 / Vorschlag vom 7. Dezember 2018 ) vereinfacht den Zugriff auf alle Gruppen im Übereinstimmungsobjekt (beachten Sie, dass Gruppe 0 die gesamte Übereinstimmung ist, während weitere Gruppen den Erfassungsgruppen im Muster entsprechen):

Mit matchAllverfügbar sind , können Sie das vermeiden whileSchleife und execmit /g... Stattdessen unter Verwendung matchAll, Sie einen Iterator zurück , die Sie mit den bequemeren verwenden können for...of, Array Verbreitung oder Array.from()Konstrukte

Diese Methode liefert eine ähnliche Ausgabe wie Regex.Matchesin C #, re.finditerin Python, preg_match_allin PHP.

Sehen Sie sich eine JS-Demo an (getestet in Google Chrome 73.0.3683.67 (offizieller Build), Beta (64-Bit)):

var myString = "key1:value1, key2-value2!!@key3=value3";
var matches = myString.matchAll(/(\w+)[:=-](\w+)/g);
console.log([...matches]); // All match with capturing group values

Die console.log([...matches])Shows

Geben Sie hier die Bildbeschreibung ein

Sie können auch Übereinstimmungswerte oder bestimmte Gruppenwerte mit abrufen

let matchData = "key1:value1, key2-value2!!@key3=value3".matchAll(/(\w+)[:=-](\w+)/g)
var matches = [...matchData]; // Note matchAll result is not re-iterable

console.log(Array.from(matches, m => m[0])); // All match (Group 0) values
// => [ "key1:value1", "key2-value2", "key3=value3" ]
console.log(Array.from(matches, m => m[1])); // All match (Group 1) values
// => [ "key1", "key2", "key3" ]

HINWEIS : Siehe Details zur Browserkompatibilität .


Perfektes Beispiel für Schlüsselwertpaare. Prägnant und leicht zu lesen, sehr einfach zu bedienen. Bei einer besseren Fehlerbehandlung gibt der Spread ein leeres Array anstelle von null zurück, sodass kein "Fehler, keine Eigenschaft" Länge "von null" mehr vorhanden ist
Jarrod McGuire

17

Ihre Syntax ist wahrscheinlich nicht die beste. FF / Gecko definiert RegExp als Erweiterung der Funktion.
(FF2 ging so weit wie typeof(/pattern/) == 'function')

Es scheint, dass dies spezifisch für FF ist - IE, Opera und Chrome werfen alle Ausnahmen dafür aus.

Verwenden Sie stattdessen eine der zuvor von anderen genannten Methoden: RegExp#execoder String#match.
Sie bieten die gleichen Ergebnisse:

var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";

regex(input);        //=> [" format_abc", "abc"]
regex.exec(input);   //=> [" format_abc", "abc"]
input.match(regex);  //=> [" format_abc", "abc"]

16

Die execMethode muss nicht aufgerufen werden! Sie können die "match" -Methode direkt für die Zeichenfolge verwenden. Vergiss nur nicht die Klammern.

var str = "This is cool";
var matches = str.match(/(This is)( cool)$/);
console.log( JSON.stringify(matches) ); // will print ["This is cool","This is"," cool"] or something like that...

Position 0 hat eine Zeichenfolge mit allen Ergebnissen. Bei Position 1 wird die erste Übereinstimmung durch Klammern dargestellt, und bei Position 2 wird die zweite Übereinstimmung in Ihren Klammern isoliert. Verschachtelte Klammern sind schwierig, also Vorsicht!


4
Ohne die globale Flagge werden alle Übereinstimmungen zurückgegeben. Damit erhalten Sie nur eine große. Achten Sie also darauf.
Shadymilkman01

8

Ein Einzeiler, der nur dann praktisch ist, wenn Sie ein einzelnes Klammerpaar haben:

while ( ( match = myRegex.exec( myStr ) ) && matches.push( match[1] ) ) {};

4
Warum nichtwhile (match = myRegex.exec(myStr)) matches.push(match[1])
Willlma

7

Verwenden Sie Ihren Code:

console.log(arr[1]);  // prints: abc
console.log(arr[0]);  // prints:  format_abc

Bearbeiten: Safari 3, wenn es darauf ankommt.


7

Mit es2018 können Sie jetzt String.match()mit benannten Gruppen Ihren regulären Ausdruck deutlicher machen, was er versucht hat.

const url =
  '/programming/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression?some=parameter';
const regex = /(?<protocol>https?):\/\/(?<hostname>[\w-\.]*)\/(?<pathname>[\w-\./]+)\??(?<querystring>.*?)?$/;
const { groups: segments } = url.match(regex);
console.log(segments);

und du wirst so etwas bekommen

{Protokoll: "https", Hostname: "stackoverflow.com", Pfadname: "Fragen / 432493 / Wie-greifen-Sie-auf-die-übereinstimmenden-Gruppen-in-einem-Javascript-regulären-Ausdruck an", Querystring: " some = parameter "}


6

function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
    matches.push(match[index]);
  }
  return matches;
}


// Example :
var myString = 'Rs.200 is Debited to A/c ...2031 on 02-12-14 20:05:49 (Clear Bal Rs.66248.77) AT ATM. TollFree 1800223344 18001024455 (6am-10pm)';
var myRegEx = /clear bal.+?(\d+\.?\d{2})/gi;

// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);

// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);

function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
    matches.push(match[index]);
  }
  return matches;
}


// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;

// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);

// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);


3

Ihr Code funktioniert für mich (FF3 auf Mac), auch wenn ich PhiLo zustimme, dass der reguläre Ausdruck wahrscheinlich sein sollte:

/\bformat_(.*?)\b/

(Aber natürlich bin ich mir nicht sicher, weil ich den Kontext der Regex nicht kenne.)


1
Es ist eine durch Leerzeichen getrennte Liste, also dachte ich, es wäre in Ordnung. seltsam, dass dieser Code für mich nicht funktionierte (FF3 Vista)
Nickf

1
Ja, wirklich seltsam. Haben Sie es alleine in der Firebug-Konsole versucht? Von einer sonst leeren Seite meine ich.
PEZ

2
/*Regex function for extracting object from "window.location.search" string.
 */

var search = "?a=3&b=4&c=7"; // Example search string

var getSearchObj = function (searchString) {

    var match, key, value, obj = {};
    var pattern = /(\w+)=(\w+)/g;
    var search = searchString.substr(1); // Remove '?'

    while (match = pattern.exec(search)) {
        obj[match[0].split('=')[0]] = match[0].split('=')[1];
    }

    return obj;

};

console.log(getSearchObj(search));

2

Es ist nicht wirklich eine explizite Schleife muß mehrere Übereinstimmungen analysieren - eine Ersatzfunktion als zweites Argument übergeben , wie beschrieben in : String.prototype.replace(regex, func):

var str = "Our chief weapon is {1}, {0} and {2}!"; 
var params= ['surprise', 'fear', 'ruthless efficiency'];
var patt = /{([^}]+)}/g;

str=str.replace(patt, function(m0, m1, position){return params[parseInt(m1)];});

document.write(str);

Das m0Argument repräsentiert die volle angepaßte Teilzeichenfolge {0}, {1}usw. m1stellt die erste Anpassungsgruppe, dh die in Klammern in den regex umschlossenen Teil , das ist 0für das erste Spiel. Und positionist der Startindex innerhalb der Zeichenfolge, in der die übereinstimmende Gruppe gefunden wurde - in diesem Fall nicht verwendet.


1

Wir können in regulären Ausdrücken auf die übereinstimmende Gruppe zugreifen, indem wir einen Backslash gefolgt von der Nummer der übereinstimmenden Gruppe verwenden:

/([a-z])\1/

In dem Code \ 1, der durch die erste Gruppe übereinstimmt ([az])


1

Einzeilige Lösung:

const matches = (text,regex) => [...text.matchAll(regex)].map(([match])=>match)

Sie können also folgendermaßen vorgehen (muss / g verwenden):

matches("something format_abc", /(?:^|\s)format_(.*?)(?:\s|$)/g)

Ergebnis:

[" format_abc"]

0

Holen Sie sich alle Gruppenvorkommen

let m=[], s = "something format_abc  format_def  format_ghi";

s.replace(/(?:^|\s)format_(.*?)(?:\s|$)/g, (x,y)=> m.push(y));

console.log(m);


0

Ich, du bist wie ich und wünschst, Regex würde ein Objekt wie dieses zurückgeben:

{
    match: '...',
    matchAtIndex: 0,
    capturedGroups: [ '...', '...' ]
}

dann schnipsen Sie die Funktion von unten

/**
 * @param {string | number} input
 *          The input string to match
 * @param {regex | string}  expression
 *          Regular expression 
 * @param {string} flags
 *          Optional Flags
 * 
 * @returns {array}
 * [{
    match: '...',
    matchAtIndex: 0,
    capturedGroups: [ '...', '...' ]
  }]     
 */
function regexMatch(input, expression, flags = "g") {
  let regex = expression instanceof RegExp ? expression : new RegExp(expression, flags)
  let matches = input.matchAll(regex)
  matches = [...matches]
  return matches.map(item => {
    return {
      match: item[0],
      matchAtIndex: item.index,
      capturedGroups: item.length > 1 ? item.slice(1) : undefined
    }
  })
}

let input = "key1:value1, key2:value2 "
let regex = /(\w+):(\w+)/g

let matches = regexMatch(input, regex)

console.log(matches)


0

BENUTZEN SIE NUR RegExp. $ 1 ... $ n-te Gruppe zB:

1.Um mit der 1. Gruppe RegExp. $ 1 übereinzustimmen

  1. Passend zur 2. Gruppe RegExp. $ 2

Wenn Sie 3 Gruppen in regulären Ausdrücken verwenden (beachten Sie die Verwendung nach string.match (reguläre Ausdrücke)).

RegExp. $ 1 RegExp. $ 2 RegExp. $ 3

 var str = "The rain in ${india} stays safe"; 
  var res = str.match(/\${(.*?)\}/ig);
  //i used only one group in above example so RegExp.$1
console.log(RegExp.$1)

//easiest way is use RegExp.$1 1st group in regex and 2nd grounp like
 //RegExp.$2 if exist use after match

var regex=/\${(.*?)\}/ig;
var str = "The rain in ${SPAIN} stays ${mainly} in the plain"; 
  var res = str.match(regex);
for (const match of res) {
  var res = match.match(regex);
  console.log(match);
  console.log(RegExp.$1)
 
}

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.