match Vs exec en JavaScript [dupliquer]
Cette question a déjà une réponse ici:
- Quelle est la différence entre la fonction Exec () de RegExp et la fonction match () de String? 5 réponses
J'ai besoin de quelques éclaircissements pour match Vs exec en JavaScript; ici quelqu'un dit que
"exec avec une expression régulière est destiné à être utilisé dans une boucle", mais d'abord de tout comme vous le voyez dans mon exemple, ce n'est pas le cas; dans mon exemple, exec avec une expression régulière globale renvoie toutes les correspondances dans un tableau! Deuxièmement, ils disent que pour la chaîne.match il renvoie tous les matchs sans avoir besoin de boucler! Mais encore une fois cela ne se produit pas dans mon exemple et il retourne simplement la chaîne d'entrée? Ai-je mal compris/fait quelque chose de mal?
var myString = "[22].[44].[33].";
var myRegexp = /.*[(d*)*].*[(d*)*].*[(d*)*].*/g;
var execResult = myRegexp.exec(myString);
console.log(execResult.length);
console.log(execResult[1]);// returns 22 and execResult has all of my matches from index 1 to the length of array
var matchResult = myString.match(myRegexp);
console.log(matchResult.length);
console.log(matchResult);// returns just myString which is "[22].[44].[33]."! Why is that?
2 réponses
string.match
trouve le premier match et le renvoie avec le match, l'indice à partir duquel le texte a été trouvé et l'entrée effective, lorsque l'indicateur n'est pas utilisé.-
string.match
renvoie simplement toutes les correspondances, lorsque le drapeau global est utilisé.var myString = "[22].[44].[33]."; console.log(myString.match(/\d+/)); # [ '22', index: 1, input: '[22].[44].[33].' ] console.log(myString.match(/\d+/g)); # [ '22', '44', '33' ]
La principale différence entre string.match
et regex.exec
est le regex
objet sera mis à jour de l'actuel match avec regex.exec
appeler. Par exemple
var myString = "[22].[44].[33].", myRegexp = /\d+/g, result;
while (result = myRegexp.exec(myString)) {
console.log(result, myRegexp.lastIndex);
}
Sera retour
[ '22', index: 1, input: '[22].[44].[33].' ] 3
[ '44', index: 6, input: '[22].[44].[33].' ] 8
[ '33', index: 11, input: '[22].[44].[33].' ] 13
Comme vous pouvez le voir, la propriété lastIndex
est mise à jour chaque fois qu'une correspondance est trouvée. Donc, garder deux choses à l'esprit lorsque vous utilisez exec
, ou , vous allez courir dans une boucle infinie.
-
Si vous n'utilisez pas l'option
g
, Vous obtiendrez toujours la première correspondance, s'il y en a une, sinonnull
. Ainsi, ce qui suit se déroulera dans une boucle infinie.var myString = "[22].[44].[33].", myRegexp = /\d+/, result; while (result = myRegexp.exec(myString)) { console.log(result, myRegexp.lastIndex); }
-
N'oubliez pas d'utiliser le même objet d'expression régulière avec les appels suivants. Parce que, l'objet regex est mis à jour à chaque fois, et si vous passez un nouvel objet, encore une fois le programme se déroulera dans une boucle infinie.
var myString = "[22].[44].[33].", result; while (result = /\d+/g.exec(myString)) { console.log(result); }
String.prototype.match()
et RegExp.prototype.exec()
sont similaires à la fois pour trouver plusieurs occurrences et les renvoyer dans un tableau. Pourtant, la méthode exec renvoie un tableau d'informations plus détaillées. Par exemple, contrairement à match, il peut également trouver plusieurs occurrences des groupes de capture. Donc si vous avez des groupes de capture, exec est essentiel. Une chose à garder à l'esprit lorsque vous travaillez avec exec, vous ne devriez pas invoquer if À partir d'une expression rationnelle littérale. Affectez d'abord votre expression rationnelle à une variable et utilisez-la pour appeler votre méthode exec. Une autre chose est, alors que match apporterait plusieurs occurrences dans un tableau d'éléments en une seule fois, avec exec, vous devez itérer pour chaque occurrence à capturer.
Invoquer match est assez simple. Comme il s'agit d'une méthode prototype de chaîne, vous l'enchaînez simplement à une chaîne et fournissez une expression rationnelle comme argument à la méthode de correspondance comme; "test".match(/es/) Une représentation littérale d'une expression régulière peut être utilisé sans problème.
Invoquer exec est plus compliqué. Comme je l'ai mentionné précédemment il est préférable d'avoir le regex assigné à quelque chose précédemment. Ok permet de voir un exemple
var text = '["job name 1","nat 1"],["job name 2","nat 2"],["job name 3","nat 3"]',
reg = /([^"]+)","([^"]+)/g,
tm = [],
te = [];
tm = text.match(reg); // tm has result of match
while(te[te.length]=reg.exec(text)); // te has result of exec + an extra null item at the end
te.length--; // te normalized.
document.write("<pre>" + JSON.stringify(tm,null,2) + "</pre>\n");
document.write("<pre>" + JSON.stringify(te,null,2) + "</pre>\n");
Comme vous le voyez, le résultat d'exec inclut également les groupes de capture. La façon dont je choisis de remplir le tableau te
est quelque peu peu orthodoxe mais je déteste utiliser un tableau temporaire juste dans la partie conditionnelle de la boucle while. Cela me semble beaucoup plus soigné. La seule chose est, le null final pour arrêter la boucle while est inséré à la fin du tableau te
. D'où l'instruction te.length--
suivante.