web-dev-qa-db-fra.com

Javascript: comment obtenir plusieurs correspondances dans les résultats RegEx .exec

Quand je cours

/(a)/g.exec('a a a ').length

Je reçois

2

mais je pensais que ça devrait revenir

3

car il y a 3 as dans la chaîne, pas 2!

Pourquoi donc?

Je veux pouvoir rechercher toutes les occurrences d'une chaîne dans RegEx et les parcourir.

FWIW: J'utilise node.js

26
Trindaz

exec() renvoie uniquement l'ensemble des captures pour la première correspondance, pas l'ensemble des correspondances comme vous vous y attendez. Donc ce que vous voyez vraiment, c'est $0 (La correspondance entière, "a") et $1 (La première capture) - c'est-à-dire. un tableau de longueur 2. exec() quant à lui est conçu pour que vous puissiez l'appeler à nouveau pour obtenir les captures pour le correspondance suivante . De MDN :

Si votre expression régulière utilise l'indicateur "g", vous pouvez utiliser la méthode exec plusieurs fois pour rechercher des correspondances successives dans la même chaîne. Lorsque vous procédez ainsi, la recherche commence à la sous-chaîne de str spécifiée par la propriété lastIndex de l'expression régulière (le test avancera également la propriété lastIndex).

35
Andrew Cheong

Vous pouvez utiliser match à la place:

'a a a'.match(/(a)/g).length  // outputs: 3
24
mVChr

Vous ne correspondez qu'au premier a. La raison pour laquelle la longueur est de deux est qu'il trouve la première correspondance et la partie de groupe entre parenthèses de la première correspondance. Dans votre cas, ce sont les mêmes.

Considérez cet exemple.

var a = /b(a)/g.exec('ba ba ba ');
alert(a);

Il génère ba, a. La longueur du tableau est toujours de 2, mais il est plus évident de savoir ce qui se passe. "ba" est le match complet. a est la première correspondance de regroupement entre parenthèses.

documentation MDN prend en charge ceci - que seule la première correspondance et les groupes contenus sont retournés. Pour trouver toutes les correspondances, vous devez utiliser match () comme indiqué par mVChr.

7
Jeanne Boyarsky

Code:

alert('a a a'.match(/(a)/g).length);

Sortie:

3
4
Ωmega

en boucle peut vous aider

x = 'a a a a';
y = new RegExp(/a/g);
while(null != (z=y.exec(x))) {
   console.log(z);     // output: object
   console.log(z[0]);  // ouput: "a"
}

Si vous ajoutez un compteur, vous obtenez sa longueur.

x = 'a a a a';
counter = 0;
y = new RegExp(/a/g);
while(null != (z=y.exec(x))) {
   console.log(z);     // output: object
   console.log(z[0]);  // output: "a"
   counter++;
}
console.log(counter);  // output: 4

C'est assez sûr, même s'il ne trouve aucune correspondance, il se termine et le compteur sera 0

L'intention principale est de dire comment RegExp peut être utilisé pour boucler et obtenir toutes les valeurs de la chaîne du même RegExp correspondant

4
ajaykools

regexp.exec(str) renvoie la première correspondance ou la correspondance entière et la première capture (lorsque re = /(a)/g;) comme mentionné dans les autres réponses

const str = 'a a a a a a a a a a a a a';
const re = /a/g;

const result = re.exec(str);
console.log(result);

Mais il se souvient également de la position après dans regexp.lastIndex propriété.

L'appel suivant commence la recherche à partir de regexp.lastIndex et renvoie la correspondance suivante.

S'il n'y a plus de correspondance, alors regexp.exec renvoie null et regexp.lastIndex est défini sur 0.

const str = 'a a a';
const re = /a/g;

const a = re.exec(str);
console.log('match : ', a, ' found at : ', re.lastIndex);

const b = re.exec(str);
console.log('match : ', b, ' found at : ', re.lastIndex);

const c = re.exec(str);
console.log('match : ', c, ' found at : ', re.lastIndex);

const d = re.exec(str);
console.log('match : ', d, ' found at : ', re.lastIndex);

const e = re.exec(str);
console.log('match : ', e, ' found at : ', re.lastIndex);

C'est pourquoi vous pouvez utiliser une boucle while qui s'arrêtera lorsque la correspondance est null

const str = 'a a a';
const re = /a/g;

while(match = re.exec(str)){
  console.log(match, ' found at : ', match.index); 
}
1
Taki