Terminologie utilisée dans cette réponse:
- Match indique le résultat de l' exécution de votre modèle RegEx contre votre chaîne comme ceci:
someString.match(regexPattern)
.
- Les modèles correspondants indiquent toutes les parties correspondantes de la chaîne d'entrée, qui résident toutes à l'intérieur du tableau de correspondance . Ce sont toutes des instances de votre modèle à l'intérieur de la chaîne d'entrée.
- Les groupes appariés indiquent tous les groupes à attraper, définis dans le modèle RegEx. (Les modèles entre parenthèses, comme ceci:,
/format_(.*?)/g
où (.*?)
serait un groupe correspondant.) Ceux-ci résident dans des modèles correspondants .
La description
Pour accéder aux groupes correspondants , dans chacun des modèles correspondants , vous avez besoin d'une fonction ou quelque chose de similaire pour itérer sur la correspondance . Il existe plusieurs façons de procéder, comme le montrent la plupart des autres réponses. La plupart des autres réponses utilisent une boucle while pour parcourir tous les modèles correspondants , mais je pense que nous connaissons tous les dangers potentiels de cette approche. Il est nécessaire de faire correspondre un new RegExp()
au lieu d'un simple motif lui-même, qui n'a été mentionné que dans un commentaire. Cela est dû au fait que la .exec()
méthode se comporte de manière similaire à une fonction de générateur - elle s'arrête à chaque fois qu'il y a une correspondance , mais continue .lastIndex
de continuer à partir de là lors du prochain .exec()
appel.
Exemples de code
Ci-dessous est un exemple de fonction searchString
qui renvoie un Array
de tous les modèles correspondants , où chacun match
est un Array
avec tous les groupes correspondants contenant . Au lieu d'utiliser une boucle while, j'ai fourni des exemples utilisant à la fois la Array.prototype.map()
fonction et une manière plus performante - en utilisant une for
boucle simple .
Versions concises (moins de code, plus de sucre syntaxique)
Celles-ci sont moins performantes car elles implémentent fondamentalement un forEach
-loop au lieu du for
-loop plus rapide.
// 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
Versions performantes (plus de code, moins de sucre syntaxique)
// 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
Je n'ai pas encore comparé ces alternatives à celles mentionnées précédemment dans les autres réponses, mais je doute que cette approche soit moins performante et moins sûre que les autres.