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_(.*?)/g
Wo (.*?)
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, searchString
die eines Array
aller übereinstimmenden Muster zurückgibt , wobei jedes match
ein Array
mit 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 for
Schleife.
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.