Betere matchresultaten met String.prototype.matchAll()

Joe Medley
Joe Medley

Chrome 73 introduceert de methode String.prototype.matchAll() . Het gedraagt ​​zich op dezelfde manier als match() , maar retourneert een iterator met alle reguliere expressie-overeenkomsten in een globale of sticky reguliere expressie. Dit biedt een eenvoudige manier om overeenkomsten te herhalen, vooral als je toegang nodig hebt om groepen vast te leggen.

Wat is er mis met match()?

Het korte antwoord is niets, tenzij je globale overeenkomsten probeert terug te geven met vastgelegde groepen. Hier is een programmeerpuzzel voor jou. Beschouw de volgende code:

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

Voer dit uit in een console en merk op dat het een array retourneert met de strings 'test1' en 'test2' . Als ik de g-vlag uit de reguliere expressie verwijder, heb ik al mijn capture-groepen, maar ik krijg alleen de eerste match. Het ziet er zo uit:

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

Deze string bevat een tweede mogelijke match die begint met 'test2' , maar die heb ik niet. Nu is hier de puzzel: hoe krijg ik alle veroveringsgroepen voor elke wedstrijd? De uitleg voor het voorstel String.prototype.matchAll() toont twee mogelijke benaderingen. Ik zal ze niet beschrijven, want hopelijk heb je ze niet lang meer nodig.

String.prototype.matchAll()

Hoe zouden de uitlegvoorbeelden eruit zien met matchAll() ? Even kijken.

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

Hierover zijn een aantal zaken op te merken. In tegenstelling tot match() dat een array retourneert bij een globale zoekopdracht, retourneert matchAll() een iterator die uitstekend werkt met for...of -lussen. De iterator produceert voor elke match een array, inclusief de capture-groepen met een paar extra's. Als je deze naar de console afdrukt, zien ze er als volgt uit:

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

Het zal je misschien opvallen dat de waarde voor elke match een array is in exact hetzelfde formaat als geretourneerd door match() voor niet-globale reguliere expressies.

Bonusmateriaal

Dit is vooral bedoeld voor mensen die nieuw zijn op het gebied van reguliere expressies of die er geen experts in zijn. Het is je misschien opgevallen dat de resultaten van zowel match() als matchAll() (voor elke iteratie) arrays zijn met enkele extra benoemde eigenschappen. Tijdens het voorbereiden van dit artikel merkte ik dat deze eigenschappen enkele tekortkomingen in de documentatie op MDN vertonen (die ik heb opgelost ). Hier is een korte beschrijving.

index
De index van het eerste resultaat in de originele tekenreeks. In het bovenstaande voorbeeld begint test2 op positie 5 en daarom heeft index de waarde 5.
input
De volledige tekenreeks waartegen matchAll() is uitgevoerd. In mijn voorbeeld was dat 'test1test2' .
groups
Bevat de resultaten van alle benoemde vastleggroepen die zijn opgegeven in uw reguliere expressie.

Conclusie

Als ik iets heb gemist, laat het me dan weten in de reacties hieronder. Meer over recente wijzigingen in JavaScript kunt u lezen in eerdere updates of op de V8-website .