Regular expressions - Deel 4

Deze pagina is op verzoek van een bezoeker teruggeplaatst.
De pagina is echter vrij oud en bevat veel afwerkingsfoutjes.
Gelieve hier rekening mee te houden.

Quantifiers: hoeveelheid

In regexen kunnen we zeggen hoeveel keer iets mag of moet voorkomen. De volgende tekens dienen hier voor: {} ? + *

Accolades: hoeveel keer iets mag voorkomen

/ab{7}c/
Dit betekent: het teken a, gevolgd door zeven keer het teken b, gevolgd door het teken c.

Dus: als achter een teken een getal tussen accolades staat, wil dat zeggen dat dat teken zoveel keer moet voorkomen als het getal zegt (in dit voorbeeld geval 7 keer).

Strings die voldoen aan het patroon:

  • abbbbbbbc
  • XYZabbbbbbbcXYZ
  • abbbbbbbcXYZ
  • =[_abbbbbbbc
  • aaaaaaaaaaaaaaaaaabbbbbbbc
Strings die niet voldoen:
  • abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
  • xabbc
  • ac

Met accolades kan ook een minimum-aantal keer, en een maximum aantal keer opgegeven worden:

/ab{4,9}c/
Dit betekent: het teken a, gevolgd door minimum 4 keer en maximum 9 keer het teken b, gevolgd door het teken c. Strings die voldoen aan het patroon:
  • 1234abbbbc789
  • 1234abbbbbc789
  • 1234abbbbbbc789
  • 1234abbbbbbbc987
  • 1234abbbbbbbbc789
  • 1234abbbbbbbbbc789
Strings die niet voldoen:
  • 1234abc
  • 1234abbbXbbbc987
  • 1234baaaaaac789
  • 1234abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc

Ook kan het maximum op oneindig gezet worden, door achter de komma gewoon geen getal te zetten maar direct de accolade te sluiten:

/ab{4,}c/
Strings die voldoen aan het patroon:
  • 4321abbbbc54
  • 4321abbbbbbbc54
  • blablablabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcdefg
Strings die niet voldoen:
  • abc
  • abbc
  • abbbc
  • bccccccccca
  • 4321abbbbXbbbc54

Ook kan nul gebruikt worden als minimum waarde, in dat geval is het teken niet verplicht voor te komen:

/ab{0,4}c/
Goed:
  • ac
  • abbbbc
Niet goed:
  • ax
  • abbbbbbbbbbbbbbbc
  • abxbc

Ik heb nu altijd voorbeelden laten zien waarbij de accolade's na gewone letters gebruikt worden, maar dit kan ook:

/x[defg]{1,4}y/
Goed:
  • xdddy
  • xdeefy
  • Xxffy
  • xey
  • xdefgy
  • fxayzant
  • ddddxddydddddddddddddddddd
Niet goed:
  • (lege string zonder inhoud)
  • xyz
  • ydddy
Het voorgaande voorbeeld zou ik graag herhalen zonder dat [defg]{1,4} direct gevolgd moet zijn door de letter y:
/x[defg]{1,4}/
Met andere woorden: wat achter de [defg]{1,4} komt, laat ik volledig vrij. "yyyxddddyyyyyyyyyyyyy" is een string die voldoet aan het patroon, en dat is logisch.
"yyyxddddddddddddddddd" is ook een string die voldoet aan het patroon. Hierdoor is "maximum 4 keer [defg]" misschien een verwarrende beschrijving. Er komen welliswaar meer dan 4 d's in voor, maar aan de voorwaarde van de regex is voldaan: in de string moet minimum 1 en maximum 4 keer [defg] voorkomen, en wat daar achter voorkomt hebben we het niet over, dus dat maakt niet uit. In dit voorbeeld is dat toevallig een hoop d's.

Vraagteken: het voorgaande teken mag, maar moet niet

Het vraagteken betekent: wat vlak voor het vraagteken staat, mag ofwel 0 keer voorkomen, ofwel 1 keer. Een vraagteken is dus hetzelfde als
{0,1}

Dus de volgende twee komen op hetzelfde neer:

/ab?c/
/ab{0,1}c/
Dit betekent: er moet eerst de letter a voorkomen, dan mag de letter b voorkomen, en dan moet de letter c voorkomen.

Vraagteken kan in combinatie met zowat alles gebruikt worden, ook met bijvoorbeeld een punt:

/ab.?cd/
betekent: eerst een a, dan een b, dan een willekeurig teken maar dat moet niet, dan een c, dan een d.

Plus (+): 1 keer of meer

Een plus (+) achter een teken, een groep, of een character class betekent dat hij minimum 1 keer, en maximum oneindig keer mag voorkomen. Een plus is dus hetzelfde als
{1,}
Bijvoorbeeld:
/ab+c/
Dit betekent: een a, gevolgd door 1 of meer b's, gevolgd door een c.

Sterretje (*): 0 keer of meer

Een sterretje achter een teken, een groep, of een character class betekent dat dat teken minimum 0 keer, en maximum oneindig keer mag voorkomen. Als het dus niet voorkomt, is het ook OK. Een sterretje betekent dus hetzelfde als:
/{0,}/
Bijvoorbeeld:
/ab*c/
Goed:
  • ac
  • abc
  • abbbbbbbc
Niet goed:
  • axc
  • abbbbxc
  • cbbbc

Een sterretje in combinatie met een punt geeft iets interessant: een willekeurig teken mag een willekeurige lengte voorkomen.

/De .* van de trap/
Dit betekent: alles is goed waar "De " in voorkomt, gevolgd door eender wat (buiten iets met een nieuwe lijn), gevolgd door " van de trap".

Goed:

  • De kat krabt de krollen van de trap
  • De van de trap (let op de dubbele spatie tussen "de" en "van")
  • blablablaDe blablabla van de trapblobloblo
Niet goed:
  • Devan de trap (let op het ontbreken van de twee spaties tussen "De" en "van". Voor een mens is dat misschien pietjepreciezerigheid, maar voor een computer is "Devan" iets totaal anders als "De van")
  • De kat krabt de krollen van de troep

Samenvatting

a{5} a moet exact 5 keer voorkomen
a{2,7} a moet minimum 2 en maximum 7 keer voorkomen
a{3,} a moet minimum 3 keer voorkomen en maximum oneindig
a+ a moet minimum 1 keer voorkomen
a? a mag voorkomen, met andere woorden: minimum 0 keer en maximum 1 keer
a* a mag voorkomen zoveel als hij wil, maar het moet niet. Met andere woorden: minimum 0 keer en maximum oneindig

Meer heeft de voorkeur

Bij een quantifier neemt de regexp altijd zoveel als mogelijk. Dit is belangrijk om te weten als we delen tekst gaan wijzigen door middel van een regexp.

Bijvoorbeeld:

/a.*a/
Hierbij zoekt de regex naar een a, dan neemt hij zoveel mogelijk tekens totdat hij een a tegenkomt.
Dus als we de string "BCDEFGHIaJKLMNOPQRSaTUVWXYZBCDEaFGHIJKLMaNOPQaRST" hebben, zal hij "aJKLMNOPQRSaTUVWXYZBCDEaFGHIJKLMaNOPQa" vinden, en niet "aJKLMNOPQRSa".

Quantifiers zijn dus gulzig, maar als dat toevallig niet zo handig is, kunnen we dat veranderen door een vraagteken te plaatsen achter de quantifier.

Opmerking: een vraagteken achter een quantifier doet dus andere dingen dan een vraagteken achter iets anders!

Als onze string dus nog steeds "BCDEFGHIaJKLMNOPQRSaTUVWXYZBCDEaFGHIJKLMaNOPQaRST" is, en we veranderen onze regexp tot:

/a.*?a/
Gaat hij dit vinden: "aJKLMNOPQRSa", en niet meer "aJKLMNOPQRSaTUVWXYZBCDEaFGHIJKLMaNOPQa"

Hij gaat niet "aFGHIJKLMaNOPQa" vinden, want een regexp werkt altijd van links naar rechts.


Volgende pagina: () ^$\A\Z