Reguliere expressies in PHP en Perl

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.

Wat?

Reguliere expressies, patroonvergelijkingen, regular expressions, of afgekort regexp of regex, is een geavanceerd systeem om met tekst om te gaan in een programmeertaal. Het is heel krachtig voor het doorzoeken, aanpassen van tekst, en voor het uitlezen van bijvoorbeeld configuratiebestanden e.d.

Deze tekst legt uit hoe zo'n regexpen werkt. Deze tekst is zowel bruikbaar voor Perl als voor PHP. Als er voorbeelden gegeven worden, worden die zowel voor PHP als Perl gegeven. Uiteraard kan je de programmeertaal waarin je niet geïnteresseerd bent niet bekijken.

Voor deze cursus is kennis van PHP of Perl dus vereist. Je moet niet alletwee kennen, een van de twee is OK.

Ik ben absoluut geen regexp-expert, dus ik kan niet garanderen dat deze tekst helemaal foutloos is.

Credits: deze handleiding is hier en daar een beetje geïnspireerd door de manual page perlrequick(1).

De return-value van een regexp

OK, praktijk. Regexpen worden dus toegepast op tekst, of in programmeer-termen: een string. Die string kan zowat overal vandaan komen: invoer van de gebruiker, een bestand, een database, een email, .... Om het eenvoudig te maken gebruik ik hier geen voorbeelden waar bijvoorbeeld nog eerst een bestand uitgelezen moet worden om aan de string te komen, maar maak ik gewoon de string aan met zijn tekstuele inhoud:

$a = "De kat krabt de krollen van de trap";
OK, we hebben dus deze string.

Met regexpen kunnen we vanalles doen, maar laten we eenvoudig beginnen: we kijken na of deze string aan een bepaald patroon voldoet.

Laten we starten met een eenvoudig voorbeeld: we zien of het woord "kat" er in voorkomt.

Perl:
$a = "De kat krabt de krollen van de trap";
$a =~ /kat/;
PHP:
$a = "De kat krabt de krollen van de trap";
preg_match ('/kat/', $a);

Maak je geen zorgen dat je nog niet goed weet wat er gebeurt, alles op zijn tijd.

Als je dit programma uitvoert zal het lijken dat er niets gebeurt. Dat is normaal: we zeggen hier enkel dat er gekeken moet worden of het woord "kat" in de string $a voorkomt. Meer staat er niet in de programmacode, dus er wordt ook niet meer gedaan.

De functie om te kijken of de string voldoet aan het patroon geeft, zoals veel functies, een waarde terug. Wat die teruggegeven waarde nu precies is, hangt af van of de string voldoet aan het patroon of niet.

  • Als de string voldoet aan het patroon geeft hij een waarde TRUE of 1 terug, die betekent dat de string voldoet aan het patroon;
  • Als de string niet voldoet aan het patroon geeft hij een waarde FALSE of 0 terug, die betekent dat de string niet voldoet aan het patroon.

Laten we dit omzetten in praktijk:

Perl:
# We maken de string $a aan en steken er een tekst in:
$a = "De kat krabt de krollen van de trap";

# We kijken door middel van een regexp-check na # of het woord kat voorkomt in de string $a # Het resultaat van die regexp-check steken # we in de variabele $b $b = $a =~ /kat/; # We drukken de variabele $b af: print ("$b\n");

# We kijken door middel van een regexp-check na # of het woord pelikaan voorkomt in de string $a # Het resultaat van die regexp-check steken # we in de variabele $b $b = $a =~ /pelikaan/; # We drukken de variabele $b af: print ("$b\n");

PHP:
// We maken de string $a aan en steken er een tekst in:
$a = "De kat krabt de krollen van de trap";

// We kijken door middel van een regexp-check na // of het woord kat voorkomt in de string $a // Het resultaat van die regexp-check steken // we in de variabele $b $b = preg_match ('/kat/', $a); // We geven de variabele $b weer: echo ($b);

// We kijken door middel van een regexp-check na // of het woord pelikaan voorkomt in de string $a // Het resultaat van die regexp-check steken // we in de variabele $b $b = preg_match ('/pelikaan/', $a); // We geven de variabele $b weer: echo ($b);

In het eerste geval wordt er netjes het getal 1 (= TRUE) afgedrukt: de variabele voldoet aan het opgegeven patroon, dus geeft de regexp TRUE terug. In het tweede geval voldoet de variabele niet aan het patroon, en geeft de regexp FALSE (0) terug. Deze waarde wordt dan afgedrukt, en dus zien we een nul.

Opmerking: als je voorbeelden probeert - wat altijd een goed idee is - let dan heel goed op het gebruik van hoofd- en kleine letters.

Nu we weten hoe we kunnen nakijken of een string voldoet aan een patroon, kunnen we dit op eender welke manier toepassen in een computerprogramma. Bijvoorbeeld in een if:

Perl:
$a = "De kat krabt de krollen van de trap";
if ($a =~ /kat/){
	print ("Het woord 'kat' is aanwezig in de opgegeven string\n");
}else{
	print ("Het woord 'kat' is niet gevonden!\n");
}
PHP:
$a = "De kat krabt de krollen van de trap";
if (preg_match ('/kat/', $a)){
	echo ("Het woord 'kat' is aanwezig in de opgegeven string");
}else{
	echo ("Het woord 'kat' is niet gevonden!");
}

Dit lijkt nu misschien een beetje dom, maar dit eenvoudig voorbeeld kent veel praktische toepassingen. We kunnen bijvoorbeeld een patroon voor een email adres maken, en dan nakijken of de bezoeker van een website wel een geldig email adres heeft ingetikt.

Opbouw van de reguliere expressie

Wat betekent nu wat in zo'n opdracht van een reguliere expressie?

Perl:
$a =~ /kat/;
Dit commando kunnen we opdelen:
$a
De variabele waarop we de reguliere expressie willen loslaten

=~
=~ wil zeggen dat we willen weten of de string voldoet (in het engels "to match") aan de reguliere expressie. Er zal 1 teruggegeven worden als de string voldoet aan de reguliere expressie, en 0 als de string niet voldoet aan de regexp.

Er bestaat ook !~
Dit geeft omgekeerd resultaat: hierbij wordt er 0 teruggegeven als de string voldoet, en 1 als de string niet voldoet.

/
De eerste slash duidt het begin aan van de eigenlijke expressie, en de tweede het einde.
Als we nu zoeken in de speciale string $_, kunnen we de =~ weglaten:
if (/kat/){
	# ...
	# ... wat er moet gebeuren als $_ aan het patroon voldoet
	# ...
}
En de volgende twee dingen komen op hetzelfde neer:
$a = 'De kat krabt de krollen van de trap';
$a =~ /kat/;
en
'De kat krabt de krollen van de trap' =~ /kat/;
PHP:
preg_match ('/kat/', $a);
preg_match is gewoon een functie zoals er zoveel zijn, waaraan we argumenten doorgeven. Het eerste argument is de string waarin we willen zoeken. Dit is een gewone doodordinaire string, we kunnen dus eigenlijk ook zo doen:
$pattern = '/kat/';
preg_match ($pattern, $a);
De eerst slash duidt het begin aan van waarop we zoeken, de tweedde het einde. Voor en achter de slashes kunnen nog opties worden meegegeven, maar daar moet je je voorlopig nog geen zorgen over maken.
Het tweede argument, in dit geval $a, is de string waarin dat we zoeken. $a is ook een doodgewone string, dus dit kan ook:
preg_match ('/kat/', 'De kat krabt de krollen van de trap');
En dingen zoals dit ook:
preg_match ('/expressiewaarmeewezoeken/', "$eenstring blablabla $eenanderestring blobloblo $nogeenanderestring");
Als je dat laatste niet snapt raad ik je aan op zoek te gaan naar uitleg over strings in PHP.


Volgende pagina: Character classes