Migliori risultati di corrispondenza con String.prototype.matchAll()

Joe Medley
Joe Medley

In Chrome 73 viene introdotto il metodo String.prototype.matchAll(). Si comporta in modo simile a match(), ma restituisce un iteratore con tutte le corrispondenze di espressione regolare in un'espressione regolare globale o persistente. Questo offre un modo semplice per eseguire l'iterazione delle corrispondenze, soprattutto quando hai bisogno dell'accesso ai gruppi di acquisizione.

Cosa c'è che non va con match()?

La risposta breve è nulla, a meno che tu non stia cercando di restituire corrispondenze globali con gruppi di acquisizione. Ecco un rompicapo di programmazione per te. Considera il seguente codice:

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const results = string.match(regex);
console.log(results);
// → ['test1', 'test2']

Esegui questo comando in una console e nota che restituisce un array contenente le stringhe 'test1' e 'test2'. Se rimuovo il flag g dall'espressione regolare, vengono visualizzati tutti i gruppi di acquisizione, ma ottengo solo la prima corrispondenza. Ha questo aspetto:

['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]

Questa stringa contiene una seconda corrispondenza possibile che inizia con 'test2', ma non ne ho. Il puzzle è: come faccio a trovare tutti i gruppi di acquisizione per ogni partita. Il spiegatore per la proposta String.prototype.matchAll() mostra due possibili approcci. Non li descriverò perché spero che non ti serviranno più a lungo.

String.prototype.matchAll()

Come sarebbero gli esempi esplicativi in matchAll()? Dai un'occhiata.

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const matches = string.matchAll(regex);
for (const match of matches) {
  console.log(match);
}

Ci sono alcuni aspetti da considerare in merito. A differenza di match(), che restituisce un array in una ricerca globale, matchAll() restituisce un iteratore che funziona in modo ottimale con i loop for...of. L'iteratore produce un array per ogni corrispondenza, inclusi i gruppi di acquisizione con alcuni extra. Se li stampi sulla console, avranno il seguente aspetto:

['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', groups: undefined]
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]

Potresti notare che il valore di ogni corrispondenza è un array nello stesso formato restituito da match() per le espressioni regolari non globali.

Materiale extra

soprattutto per persone che non hanno familiarità con le espressioni regolari o non ne hanno esperienza. Forse hai notato che i risultati sia di match() che di matchAll() (per ogni iterazione) sono array con alcune proprietà denominate aggiuntive. Durante la preparazione di questo articolo, ho notato che queste proprietà presentano alcune carenze nella documentazione su MDN (che ho risolto). Di seguito puoi trovare una breve descrizione.

index
L'indice del primo risultato nella stringa originale. Nell'esempio precedente, test2 inizia dalla posizione 5, quindi index ha il valore 5.
input
La stringa completa in base a cui è stato eseguito matchAll(). Nel mio esempio, era 'test1test2'.
groups
Contiene i risultati di qualsiasi gruppo di acquisizione con nome specificato nell'espressione regolare.

Conclusione

Se mi sono sfuggito qualcosa, faccelo sapere nei commenti qui sotto. Puoi scoprire di più sulle recenti modifiche a JavaScript negli aggiornamenti precedenti o sul sito web della V8.