Espressioni regolari e sub-match JavaScript

Perché le sotto-corrispondenze di Javascript smettono di funzionare quando viene impostato il modificatore g ?

 var text = 'test test test test'; var result = text.match(/t(e)(s)t/); // Result: ["test", "e", "s"] 

Quanto sopra funziona bene, il result[1] è "e" e il result[2] è "s" .

 var result = text.match(/t(e)(s)t/g); // Result: ["test", "test", "test", "test"] 

Quanto sopra ignora i miei gruppi di cattura. La seguente è l’unica soluzione valida?

 var result = text.match(/test/g); for (var i in result) { console.log(result[i].match(/t(e)(s)t/)); } /* Result: ["test", "e", "s"] ["test", "e", "s"] ["test", "e", "s"] ["test", "e", "s"] */ 

L’uso della funzione match() String non restituirà i gruppi catturati se il modificatore globale è impostato, come hai scoperto.

In questo caso, si vorrebbe usare un object RegExp e chiamare la sua funzione exec() . String match() String match() è quasi identica alla funzione exec() di RegExp … tranne in casi come questi. Se il modificatore globale è impostato, la funzione match() normale non restituirà i gruppi catturati, mentre la funzione exec() RegExp farà. (Notato qui , tra gli altri posti.)

Un’altra cosa da ricordare è che exec() non restituisce le corrispondenze in un unico grande array: continua a restituire le corrispondenze finché non si esaurisce, nel qual caso restituisce null .

Ad esempio, potresti fare qualcosa del genere:

 var pattern = /t(e)(s)t/g; // Alternatively, "new RegExp('t(e)(s)t', 'g');" var match; while (match = pattern.exec(text)) { // Do something with the match (["test", "e", "s"]) here... } 

Un’altra cosa da notare è che RegExp.prototype.exec() e RegExp.prototype.test() eseguono l’espressione regolare sulla stringa fornita e restituiscono il primo risultato. Ogni chiamata sequenziale passerà attraverso il set di risultati aggiornando RegExp.prototype.lastIndex base alla posizione corrente nella stringa.

Ecco un esempio: // ricorda che ci sono 4 corrispondenze nell’esempio e nel modello. lastIndex inizia da 0

 pattern.test(text); // pattern.lastIndex = 4 pattern.test(text); // pattern.lastIndex = 9 pattern.exec(text); // pattern.lastIndex = 14 pattern.exec(text); // pattern.lastIndex = 19 // if we were to call pattern.exec(text) again it would return null and reset the pattern.lastIndex to 0 while (var match = pattern.exec(text)) { // never gets run because we already traversed the string console.log(match); } pattern.test(text); // pattern.lastIndex = 4 pattern.test(text); // pattern.lastIndex = 9 // however we can reset the lastIndex and it will give us the ability to traverse the string from the start again or any specific position in the string pattern.lastIndex = 0; while (var match = pattern.exec(text)) { // outputs all matches console.log(match); } 

Puoi trovare informazioni su come utilizzare gli oggetti RegExp su MDN (in particolare, ecco la documentazione per la funzione exec() ).