Leren Regex: A Beginner's Guide
In deze gids leert u regex, of reguliere expressie syntaxis. Aan het eind van de handleiding zult u in staat zijn om regex oplossingen toe te passen in de meeste scenario’s die er om vragen in uw web ontwikkelingswerk.
Reguliere expressies kennen vele toepassingen, waaronder:
- validatie van formulierinvoer
- web scraping
- zoeken en vervangen
- filtering voor informatie in grote tekstbestanden zoals logs
Reguliere expressies, of regex zoals ze meestal worden genoemd, zien er voor nieuwe gebruikers ingewikkeld en intimiderend uit. Kijk maar eens naar dit voorbeeld:
/^+@+(?:\.+)*$/
Het ziet er gewoon uit als verminkte tekst. Maar wanhoop niet, er zit een methode achter deze waanzin.
Credit: xkcd
Ik zal je laten zien hoe je reguliere expressies in een mum van tijd onder de knie krijgt. Laten we eerst de terminologie verduidelijken die in deze gids wordt gebruikt:
- patroon: reguliere expressiepatroon
- string: teststring die wordt gebruikt om het patroon te matchen
- cijfer: 0-9
- letter: a-z, A-Z
- symbool: !$%^&*()_+|~-=`{}:”;'<>?,./
- spatie: enkele spatie, tab
- teken: verwijst naar een letter, cijfer of symbool
Basics
Om snel regex te leren met deze gids, bezoek Regex101, waar je regex patronen kunt maken en testen tegen strings (tekst) die je aanlevert.
Wanneer je de site opent, moet je de JavaScript smaak selecteren, want dat is wat we zullen gebruiken voor deze gids. (De syntaxis van Regex is voor alle talen gelijk, maar er zijn een paar kleine verschillen.)
Na het openen van de site moet je de global
en multi line
vlaggen in Regex101 uitschakelen. We zullen ze in de volgende sectie behandelen. Voor nu zullen we kijken naar de eenvoudigste vorm van reguliere expressie die we kunnen bouwen. Voer het volgende in:
- regex invoerveld: cat
- test string: rat bat cat zat fat cats eat tat cat mat CAT
Bedenk dat reguliere expressies in JavaScript beginnen en eindigen met /
. Als u een reguliere expressie in JavaScript-code zou schrijven, zou deze er als volgt uitzien: /cat/
zonder aanhalingstekens. In de bovenstaande staat komt de reguliere expressie overeen met de string “cat”. Echter, zoals je kunt zien in de afbeelding hierboven, zijn er verschillende “cat” strings die niet worden gematched. In de volgende sectie zullen we bekijken waarom.
Globale en hoofdletterongevoelige Regex Vlaggen
In de standaardinstelling geeft een regex patroon alleen de eerste overeenkomst terug die het vindt. Als u meer overeenkomsten wilt, moet u de globale vlag inschakelen, aangeduid als g
. Regex patronen zijn standaard ook hoofdlettergevoelig. U kunt dit gedrag opheffen door de ongevoelige vlag aan te zetten, aangeduid met i
. Het bijgewerkte regex-patroon is nu volledig uitgedrukt als /cat/gi
. Zoals u hieronder kunt zien, zijn alle “cat”-tekenreeksen gematcht, inclusief die met een andere hoofdletter.
Karaktersets
In het vorige voorbeeld hebben we geleerd hoe we exacte hoofdlettergevoelige overeenkomsten kunnen uitvoeren. Wat als we “bat”, “cat”, en “fat” willen matchen. We kunnen dit doen door gebruik te maken van karaktersets, aangeduid met . In principe zet je er meerdere karakters in die je gematched wilt hebben. Bijvoorbeeld, at
zal overeenkomen met meerdere reeksen als volgt:
Tekensets werken ook met cijfers.
Ranges
Laten we aannemen dat we willen overeenkomen met alle woorden die eindigen op at
. We zouden het volledige alfabet in de karakterset kunnen invoeren, maar dat zou omslachtig zijn. De oplossing is om reeksen als deze te gebruiken at
:
Hier is de volledige reeks die wordt getest: rat bat cat sat fat cats eat tat cat dog mat CAT
.
Zoals u kunt zien, komen alle woorden overeen zoals verwacht. Ik heb het woord dog
toegevoegd om een ongeldige overeenkomst toe te voegen. Hier zijn andere manieren waarop u bereiken kunt gebruiken:
-
Partieel bereik: selecties zoals
of
.
-
Gekapitaliseerd bereik:
.
-
Cijferbereik:
.
-
Symboolbereik: bijvoorbeeld
.
-
Gemengd bereik: bijvoorbeeld
omvat alle cijfers, kleine letters en hoofdletters. Houd er rekening mee dat een bereik alleen meerdere alternatieven specificeert voor een enkel teken in een patroon.
Om verder te begrijpen hoe u een bereik definieert, kunt u het beste naar de volledige ASCII-tabel kijken om te zien hoe tekens zijn geordend.
Herhalende tekens
Stel dat u wilt overeenkomen met alle drieletterwoorden. U zou het waarschijnlijk als volgt doen:
Dit zou overeenkomen met alle drie-letter woorden. Maar wat als u een woord van vijf of acht karakters wilt gebruiken. De bovenstaande methode is omslachtig. Er is een betere manier om zo’n patroon uit te drukken met de {}
accolades notatie. U hoeft alleen maar het aantal herhalende tekens op te geven. Hier zijn voorbeelden:
-
a{5}
komt overeen met “aaaaa”. -
n{3}
komt overeen met “nnn”. -
{4}
komt overeen met elk woord van vier letters, zoals “deur”, “kamer” of “boek”. -
{6,}
komt overeen met elk woord van zes of meer letters. -
{8,11}
komt overeen met elk woord van acht tot 11 letters. Basis wachtwoord validatie kan op deze manier worden gedaan. -
{11}
zal overeenkomen met een 11-cijferig nummer. Basis internationale telefoon validatie kan op deze manier worden gedaan.
Metacharacters
Metacharacters staan u toe om reguliere expressie patronen te schrijven die nog compacter zijn. Laten we ze een voor een doornemen:
-
\d
komt overeen met elk cijfer dat hetzelfde is als -
\w
komt overeen met elke letter, elk cijfer en elk onderstrepingsteken -
\s
komt overeen met een witruimteken – dat wil zeggen, een spatie of tab -
\t
komt alleen overeen met een tab-teken
Vanuit wat we tot nu toe hebben geleerd, kunnen we reguliere expressies als volgt schrijven:
-
\w{5}
komt overeen met elk woord van vijf letters of een getal van vijf cijfers -
\d{11}
komt overeen met een getal van 11 cijfers, zoals een telefoonnummer
Speciale tekens
Speciale tekens brengen ons een stap verder in het schrijven van meer geavanceerde patroonexpressies:
-
+
: Een of meer kwantoren (het voorafgaande teken moet bestaan en kan optioneel worden gedupliceerd). Bijvoorbeeld, de uitdrukkingc+at
komt overeen met “cat”, “ccat” en “ccccccat”. U kunt het voorgaande teken zo vaak herhalen als u wilt en u krijgt nog steeds een overeenkomst. -
?
: Nul of één kwantor (het voorafgaande teken is optioneel). Bijvoorbeeld, de uitdrukkingc?at
komt alleen overeen met “cat” of “at”. -
*
: Nul of meer kwantoren (het voorafgaande teken is optioneel en kan optioneel worden gedupliceerd). Bijvoorbeeld, de uitdrukkingc*at
komt overeen met “at”, “cat” en “ccccccat”. Het is als de combinatie van+
en?
. -
\
: dit “escape karakter” wordt gebruikt wanneer we een speciaal karakter letterlijk willen gebruiken.c\*
zal bijvoorbeeld precies overeenkomen met “c*” en niet met “ccccccc”. -
: deze “negatie”-notatie wordt gebruikt om een teken aan te geven dat niet binnen een bereik moet worden gevonden. De uitdrukking
bld
zal bijvoorbeeld niet overeenkomen met “bald” of “bbld” omdat de tweede letters a tot c negatief zijn. Het patroon komt echter wel overeen met “beld”, “bild”, “bold” enzovoort. -
.
: deze “do”-notatie komt overeen met elk cijfer, letter of symbool behalve newline. Zo komt.{8}
overeen met een wachtwoord van acht tekens dat bestaat uit letters, cijfers en symbolen. “password” en “P@ssw0rd” komen bijvoorbeeld beide overeen.
Van wat we tot nu toe hebben geleerd, kunnen we een interessante variëteit aan compacte maar krachtige reguliere expressies maken. Bijvoorbeeld:
-
.+
komt overeen met een of een onbeperkt aantal tekens. Bijvoorbeeld, “c” , “cc” en “bcd#.670” zullen allemaal overeenkomen. -
+
zal overeenkomen met alle kleine letter woorden, ongeacht de lengte, zolang ze ten minste een letter bevatten. Bijvoorbeeld, “boek” en “directiekamer” zullen beide overeenkomen.
Groepen
Alle speciale karakters die we zojuist hebben genoemd hebben alleen invloed op een enkel karakter of een reeks reeksen. Wat als we het effect willen laten gelden voor een gedeelte van de expressie? Dat kunnen we doen door groepen te maken met ronde haakjes – ()
. Bijvoorbeeld, het patroon book(.com)?
zal overeenkomen met zowel “book” als “book.com”, omdat we het “.com” gedeelte optioneel hebben gemaakt.
Hier volgt een complexer voorbeeld dat gebruikt zou worden in een realistisch scenario zoals e-mail validatie:
- patroon:
@\w+\.\w{2,3}(\.\w{2,3})?
- test string:
abc.com abc@mail @mail.com @mail.co.ke
Alternatieve tekens
In regex kunnen we alternatieve tekens opgeven met het “pipe”-symbool – |
. Dit is anders dan de speciale tekens die we eerder hebben laten zien, omdat het alle tekens aan elke kant van het pijp-symbool beïnvloedt. Bijvoorbeeld, het patroon sat|sit
komt overeen met zowel “sat” als “sit” strings. We kunnen het patroon herschrijven als s(a|i)t
om met dezelfde tekenreeksen overeen te komen.
Het bovenstaande patroon kan worden uitgedrukt als s(a|i)t
door ()
haakjes te gebruiken.
Begin- en eindpatronen
Het is u misschien opgevallen dat sommige positieve overeenkomsten het resultaat zijn van gedeeltelijke overeenstemming. Bijvoorbeeld, als ik een patroon heb geschreven dat overeenkomt met de string “boo”, dan zal de string “book” ook een positieve overeenkomst krijgen, ondanks dat het geen exacte overeenkomst is. Om dit te verhelpen, gebruiken we de volgende notaties:
-
^
: aan het begin geplaatst, komt dit teken overeen met een patroon aan het begin van een string. -
$
: aan het eind geplaatst, komt dit teken overeen met een patroon aan het eind van de string.
Om de bovenstaande situatie op te lossen, kunnen we ons patroon schrijven als boo$
. Dit zal ervoor zorgen dat de laatste drie karakters overeenkomen met het patroon. Er is echter een probleem waar we nog geen rekening mee hebben gehouden, zoals de volgende afbeelding laat zien:
De string “sboo” krijgt een overeenkomst omdat het nog steeds voldoet aan de huidige eisen voor het matchen van patronen. Om dit op te lossen, kunnen we het patroon als volgt bijwerken: ^boo$
. Dit zal strikt overeenkomen met het woord “boo”. Als je ze allebei gebruikt, worden beide regels afgedwongen. Bijvoorbeeld, ^{5}$
komt overeen met een woord van vijf letters. Als de string meer dan vijf letters heeft, komt het patroon niet overeen.
Regex in JavaScript
// Example 1const regex1=/a-z/ig//Example 2const regex2= new RegExp(//, 'ig')
Als u Node.js op uw machine hebt geïnstalleerd, opent u een terminal en voert u het commando node
uit om de Node.js shell-interpreter te starten. Voer vervolgens het volgende uit:
Voel je vrij om met meer regexpatronen te spelen. Als u klaar bent, gebruikt u het commando .exit
om de shell af te sluiten.
Real World Example: E-mail Validatie
Als afsluiting van deze gids, laten we eens kijken naar een populair gebruik van regex, e-mail validatie. (We willen bijvoorbeeld controleren of een e-mailadres dat een gebruiker in een formulier heeft ingevuld, een geldig e-mailadres is.)
Dit onderwerp is gecompliceerder dan je zou denken. De syntaxis van het emailadres is vrij eenvoudig: {name}@{domain}
. In theorie kan een e-mail adres een beperkt aantal symbolen bevatten, zoals #-@&%.
enz. De plaatsing van deze symbolen is echter van belang. Mailservers hebben ook verschillende regels voor het gebruik van symbolen. Sommige servers behandelen bijvoorbeeld het symbool +
als ongeldig. In andere mailservers wordt het symbool gebruikt voor subadressering van e-mail.
Probeer als uitdaging om uw kennis te testen een regelmatig expressiepatroon te maken dat alleen overeenkomt met de geldige e-mailadressen die hieronder zijn gemarkeerd:
# invalid emailabcabc.com# valid email [email protected]@[email protected]@[email protected]# invalid email [email protected]@[email protected]#[email protected]# valid email [email protected]@[email protected][email protected]# invalid domain [email protected]@mail#[email protected]@mail..com# valid domain [email protected]@[email protected]@[email protected]
Bedenk wel dat sommige e-mailadressen die als geldig zijn gemarkeerd, voor bepaalde organisaties ongeldig kunnen zijn, terwijl sommige adressen die als ongeldig zijn gemarkeerd, bij andere organisaties juist wel zijn toegestaan. Hoe dan ook, leren om aangepaste reguliere expressies te maken voor de organisaties waar u voor werkt is van het grootste belang om aan hun behoeften te voldoen. In het geval dat u vastloopt, kunt u kijken naar de volgende mogelijke oplossingen. Merk op dat geen van deze oplossingen 100% overeenkomt met de geldige e-mailtestreeksen.
- Mogelijke oplossing 1:
^\w*(\-\w)?(\.\w*)?@\w*(-\w*)?\.\w{2,3}(\.\w{2,3})?$
- Mogelijke oplossing 2:
^((\.,;:\s@"]+(\.\.,;:\s@"]+)*)|(".+"))@((\{1,3}\.{1,3}\.{1,3}\.{1,3}])|((+\.)+{2,}))$
Samenvatting
Ik hoop dat u nu de basis hebt geleerd van reguliere expressies. We hebben niet alle regex functies behandeld in deze snelle beginners gids, maar je zou genoeg informatie moeten hebben om de meeste problemen aan te pakken die om een regex oplossing vragen. Lees voor meer informatie onze gids over best practices voor de praktische toepassing van regex in real-world scenario’s.