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()
).