In onze vorige zelfstudie over reguliere expressies in JavaScript, hebt u geleerd over het nut van reguliere expressies en hoe u enkele van uw eigen uitdrukkingen kunt schrijven om eenvoudige patronen aan te passen.
Na het lezen van de vorige tutorial, zou je nu een goed begrip moeten hebben van speciale karakters zoals een backslash en karaktersequenties zoals \ w
of \ w
. Hier is een heel snelle samenvatting van die karakterreeksen:
\ d
of \ D
om respectievelijk een cijfer of een niet-cijferig teken in een gegeven reeks te evenaren. Cijfertekens zijn 0, 1, 2, 3, 4, 5, 6, 7, 8 en 9. Alle andere tekens komen overeen met \ D
.\ w
of \ w
om een woord of niet-woordteken in een gegeven reeks te matchen. Woordtekens bevatten alfabetten, cijfers en onderstrepingstekens. Al het andere, zoals €,%, enz., Wordt als een niet-woordkarakter beschouwd.\ s
of \ S
om tekenruimtetekens of niet-spaties in een tekenreeks overeen te laten komen. Ruimtetekens omvatten spatie, tab, formulierinvoer en regelinvoer.In plaats van één karakter per keer aan te passen, kunt u het *
symbool om de voorgaande uitdrukking nul of meer keer overeen te laten komen. De +
teken zal 1 of meerdere keren op dezelfde manier overeenkomen met de voorgaande uitdrukking.
U kunt een patroon een bepaald aantal keren matchen door het toe te voegen n, m
ernaar toe. Hier, n
is het minimumaantal keren dat u het wilt evenaren, en m
is de maximale limiet. Als u geen waarde opgeeft voor m
, de voorgaande uitdrukking zal zo vaak mogelijk worden vergeleken.
Bekijk mijn vorige zelfstudie als iets dat we net hebben behandeld niet duidelijk is. Ik heb daar alles in meer detail uitgelegd.
Laten we nu verder gaan met een aantal meer verfijnde tekenreeksen in reguliere expressies, zodat u er het maximale uit kunt halen en erachter kunt komen hoe u uitdrukkingen kunt schrijven die overeenkomen met ingewikkelde patronen.
?
KarakterDe ?
karakter betekent verschillende dingen in verschillende situaties.
Wanneer het alleen wordt gebruikt, komt dit overeen met de uitdrukking die er 0 of 1 voor kwam. In deze zin is het hetzelfde als 0,1
.
Je kan ook gebruiken ?
onmiddellijk nadat andere kwantoren zoals *
, +
en om het minimaal mogelijke aantal tekens overeen te laten komen. Met andere woorden, het zal die hebberige kwantoren veranderen in niet-hebberig. Dit kan een beetje moeilijk te begrijpen zijn zonder naar live voorbeelden te kijken, dus laten we eerst een voorbeeld bekijken.
Beschouw de volgende zin:
Ik heb 17321HDGE als gebruikersnaam toegewezen gekregen terwijl mijn vriend FHES193EK1 kreeg toegewezen.
Laten we nu alle overeenkomsten bekijken die door verschillende kwantoren en hun niet-hebzuchtige tegenpartij zouden zijn geretourneerd.
Als we de uitdrukking gebruiken / \ D + / g
in het voorbeeld komt het overeen met een of meer opeenvolgende cijfertekens. Vanwege de wereldwijde vlag zijn er drie wedstrijden: 17321, 193, en 1.
Dat zou je moeten opmerken 193 en 1 worden beschouwd als verschillende overeenkomsten omdat ze gescheiden zijn door EK.
In het volgende voorbeeld worden de overeenkomsten weergegeven zonder het gebruik van kwantoren.
var re = / \ d + / g; var count = 0; var textString = "Ik heb 17321HDGE toegewezen als gebruikers-id terwijl mijn vriend FHES193EK1 kreeg toegewezen."; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); tel ++; console.log ("Total Matches:" + count); / * Uitgang 17321 193 1 Totaal aantal overeenkomsten: 3 * /
Nu, het toevoegen van een ?
karakter na \ d+
zal negen verschillende wedstrijden retourneren. Eigenlijk, / \ D +? /
verandert elk cijfer in een afzonderlijke overeenkomst. Waarom is dat?
Het is omdat \ d+
wordt per definitie geacht overeen te komen met een of meer cijfers. Sinds de ?
Het karakter moet overeenkomen met het minimaal mogelijke aantal tekens, het komt overeen met een enkel cijfer per keer.
De niet-hebberig ?
kwantifier zal deze keer 9 kleinere eencijferige overeenkomsten retourneren. Kortheidshalve heb ik de regel uitgelogd die de wedstrijden in console logt.
var re = / \ d +? / g; var count = 0; var textString = "Ik heb 17321HDGE toegewezen als gebruikers-id terwijl mijn vriend FHES193EK1 kreeg toegewezen."; var match = re.exec (textString); while (match! == null) // console.log (match [0]); match = re.exec (textString); tel ++; console.log ("Total Matches:" + count); / * Output Totaal aantal overeenkomsten: 9 * /
Laten we nog een voorbeeld nemen. De reguliere expressie / \ W + /
zal woordtekens behouden zolang ze niet worden onderbroken door een niet-woordteken zoals spatie. In ons geval komt het overeen met hele door de ruimte gescheiden woorden zoals toegewezen en 17321HDGE een keer.
Als we onze oorspronkelijke reguliere expressie vervangen door / \ W + /
, we krijgen 14 verschillende wedstrijden. In principe zal elk woord zijn eigen match zijn. U kunt de uitvoer zelf zien door de regel uit te spreken.
var re = / \ w + / g; var count = 0; var textString = "Ik heb 17321HDGE toegewezen als gebruikers-id terwijl mijn vriend FHES193EK1 kreeg toegewezen."; var match = re.exec (textString); while (match! == null) // console.log (match [0]); match = re.exec (textString); tel ++; console.log ("Total Matches:" + count); / * Totale output van uitvoer: 14 * /
Nu verandert de expressie naar / \ W +? /
zal elk woordkarakter als een afzonderlijke overeenkomst retourneren en u krijgt 68 overeenkomsten.
Laten we nog een laatste voorbeeld bekijken voordat we verder gaan. De reguliere expressie / \ W 4 /
zal alle woorden in onze zin retourneren die uit vier tekens of langer bestaan. Dus het komt overeen hebben, geweest, toegewezen, en 17321HDGE, onder andere. Draai het nu om / \ W 4? /
zou meerdere overeenkomsten retourneren van woorden met meer dan vier tekens. In ons voorbeeld zouden de geretourneerde wedstrijden zijn hebben, geweest, assi, gned, 1732, en 1HGD. Het personage E aan het einde van 17321HDGE maakt geen deel uit van een wedstrijdomdat het niet in de groep van vier opeenvolgende woordtekens kan voorkomen.
var re = / \ w 4, / g; var count = 0; var textString = "Ik heb 17321HDGE toegewezen als gebruikers-id terwijl mijn vriend FHES193EK1 kreeg toegewezen."; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); tel ++; console.log ("Total Matches:" + count); / * Uitgang is toegewezen 17321HDGE-gebruiker terwijl vriend FHES193EK1 heeft toegewezen Totaal aantal overeenkomsten: 9 * /
In mijn vorige regex zelfstudie heb ik kort uitgelegd hoe haakjes kunnen worden gebruikt om een deel van een wedstrijd te onthouden. Bij gebruik met een ?
karakter, ze kunnen ook andere doelen dienen.
Soms wilt u dat een groep tekens overeenkomt als een eenheid. U zou bijvoorbeeld kunnen zoeken naar de occurrences van na een of twee keer als een overeenkomst in de volgende tekst.
na naa nnaa nana naana
Ter verduidelijking, u zoekt de vetgedrukte tekst als overeenkomsten: na naeen nnaeen (Nana) naeenna. Het gedeelte tussen de haakjes hoort overeen te komen als een eenheid, dus telt het gewoon als één overeenkomst.
Bijna iedereen die net begint met regex zal de uitdrukking gebruiken / Na 1,2 /
met de bedoeling om het verwachte resultaat te krijgen. In hun gedachten, de 1,2 deel hoort overeen te komen met een of twee exemplaren van n en een samen. Het komt echter overeen met een enkele occurrence van n gevolgd door 1 of 2 exemplaren van het teken een.
Ik heb de wedstrijden geretourneerd door / Na 1,2 /
vetgedrukt voor verduidelijking: na naa nnaa (Na) (na) (Naa) (na). De delen tussen de haakjes zijn afzonderlijke overeenkomsten. Zoals je ziet, krijgen we niet het gewenste resultaat omdat 1,2
overweegt het niet na om een enkele eenheid te zijn die moet worden vergeleken.
De oplossing hier is om haakjes te gebruiken om JavaScript te laten matchen na als een eenheid. Zoals we in de vorige zelfstudie echter hebben gezien, begint JavaScript de koppeling te herinneren vanwege de haakjes.
Als u niet wilt dat JavaScript de wedstrijd onthoudt, moet u toevoegen ?:
vóór de groep tekens die u probeert aan te passen. In ons geval zou de uiteindelijke uitdrukking worden / (?: na) 1,2 /
. De groep na wordt nu als een eenheid gekoppeld en wordt niet onthouden. Ik heb de laatste overeenkomsten gemarkeerd die zijn geretourneerd met deze uitdrukking vetgedrukt: na naeen nnaeen (nana) naeenna.
In het volgende voorbeeld worden alle overeenkomsten geregistreerd bij console. Aangezien er 6 totale wedstrijden zijn, is de totale telling 6.
var re = / (?: na) 1,2 / g; var count = 0; var textString = "na naa nnaa nana naana"; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); tel ++; console.log ("Total Matches:" + count); / * Output na na nana na na Totaal aantal overeenkomsten: 6 * /
Er zijn veel situaties waarin we een bepaalde reeks tekens willen matchen, maar alleen als ze al dan niet worden gevolgd door een andere reeks tekens. U zou bijvoorbeeld naar het woord kunnen zoeken appels in een tekst, maar alleen die wedstrijden willen die gevolgd worden door zijn. Beschouw de volgende zin.
appels zijn lekker. We aten de hele dag appels. Iedereen die appels at, vond ze leuk.
In het bovenstaande voorbeeld willen we alleen het eerste woord als overeenkomst. Elk ander voorkomen van het woord hoort niet in de wedstrijden te staan.
Een manier om dit te bereiken, is door de volgende reguliere expressie te gebruiken a (? = b)
. Het woord dat we willen matchen is een, en het woord dat erachter zou moeten komen een is b. In ons geval zou de uitdrukking worden / Appels (? = \ Sare) /
. Onthoud dat het woord zijn is niet opgenomen in deze wedstrijd.
var re = / apples (? = \ sare) / g; var count = 0; var textString = "appels zijn lekker, we hebben de hele dag appels gegeten, iedereen die appels at, vond ze lekker."; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); tel ++; console.log ("Total Matches:" + count); / * Outputappels Totaal aantal overeenkomsten: 1 * /
Deze reguliere expressie, waarin we kijken naar wat erna in de string komt voordat we beslissen of het woord een match is, wordt een lookahead genoemd.
Een zeer vergelijkbare situatie zou zich voordoen als u zou besluiten om overeen te komen appels alleen als het was niet gevolgd door een specifieke reeks tekens. In dergelijke gevallen moet u vervangen ?=
met ?!
in je reguliere expressie. Als we alle keren op zoek waren naar appels welke zijn niet gevolgd door zijn, we zullen gebruiken / Appels (?! \ Sare) /
als onze reguliere expressie. Er zullen twee succesvolle wedstrijden zijn voor onze testzin.
var re = / apples (?! \ sare) / g; var count = 0; var textString = "appels zijn lekker, we hebben de hele dag appels gegeten, iedereen die appels at, vond ze lekker."; var match = re.exec (textString); while (match! == null) console.log (match [0]); match = re.exec (textString); tel ++; console.log ("Total Matches:" + count); / * Output appels appelen Totaal aantal overeenkomsten: 2 * /
Nog een ding: u hoeft geen twee afzonderlijke reguliere expressies te gebruiken om alle overeenkomsten te vinden die worden gevolgd door een van de twee opgegeven woorden. Het enige wat je hoeft te doen is de pipe-operator tussen die woorden toevoegen, en je bent klaar om te gaan. Bijvoorbeeld als u op zoek bent naar alle exemplaren van appel die worden gevolgd door zijn of waren, je zou ... moeten gebruiken / Appels (\ Sare |?! \ Swere) /
als je reguliere expressie.
In deze zelfstudie leerden we ingewikkelde reguliere expressies te schrijven die pasten bij de patronen waarnaar we op zoek waren. We kunnen de special gebruiken ?
teken om het minimaal vereiste aantal van het voorgaande teken als overeenkomst te retourneren. Evenzo kunnen we de ?
tussen haakjes om ervoor te zorgen dat de groep die we overeenkwamen niet wordt onthouden.
Uiteindelijk hebben we geleerd dat het ?=
en ?!
tekenreeksen in een reguliere expressie geven ons de mogelijkheid om een bepaalde reeks tekens als overeenkomst alleen terug te geven als ze al dan niet worden gevolgd door een andere gegeven reeks tekens.
Als je vragen hebt over deze tutorial, laat het me dan gerust weten en ik zal mijn best doen om ze uit te leggen.