grep(pattern = "Wit", x = c("Rood", "Wit", "Blauw", "Violet"))
[1] 2
Een handleiding voor beginners
Ben Welman
22 juli 2025
Regular Expressions (vaak afgekort als regex of regexp) zijn patronen die gebruikt worden om tekst te zoeken, te matchen en te manipuleren. Je kunt ze zien als een krachtige zoekfunctie die niet alleen naar exacte woorden zoekt, maar naar patronen in tekst.
Stel je voor dat je in een document wilt zoeken naar alle Nederlandse telefoonnummers, e-mailadressen, of postcodes. In plaats van elk mogelijk nummer handmatig te typen, kun je een regex-patroon maken dat alle mogelijke varianten herkent.
Toepassingsgebieden
Regular expressions worden veel gebruikt voor:
De eenvoudigste regex matcht exacte tekens.
hallo
matcht alleen het woord “hallo”.
Regex heeft speciale tekens (metacharacters) met bijzondere betekenissen: \^.|?*+(){}$
Wanneer je een van deze tekens als letterlijke tekst wilt opnemen moet je deze escapen met \
.
Matcht elk willekeurig teken (behalve newline).
h.llo
matcht “hallo”, “hello”, “h3llo”, “h@llo”
Matcht het voorgaande teken 0 of meer keer.
ha*llo
matcht “hllo”, “hallo”, “haallo”, “haaallo”
Matcht het voorgaande teken 1 of meer keer.
ha+llo
matcht “hallo”, “haallo”, “haaallo” (maar niet “hllo”)
Matcht het voorgaande teken 0 of 1 keer, maakt het dus in feite optioneel.
ha?llo
matcht “hllo”, “hallo” (maar niet “haallo”)
Betekent OF
x|y
matcht zowel “x” als “y”
Met blokhaken []
kun je een set van tekens definiëren:
[abc]
Matcht één karakter uit de lijst: “a”, “b”, of “c”
Een bereik van tekens definieer je met een -
ertussen. Je kunt combinaties maken door de reeksen achter elkaar te plaatsen zonder scheidingssymbool.
[a-z] # een kleine letter
[A-Z] # een hoofdletter
[0-9] # een cijfer
[1-49] # een van de cijfers 1, 2, 3, 4, 9 (PAS OP niet 1 t/m 49)
[a-zA-Z] # een kleine letter of een hoofdletter
[a-z0-9] # een kleine letters of een cijfer
[ ] # blanco (" ")
Ontkenning van reeksen kan door een caret ^
te plaatsen direct na de openende blokhaak. De caret betekent NIET.
[^0-9] # geen cijfer
Matcht alles BEHALVE cijfers
\d # een willekeurig cijfer, gelijk aan [0-9]
\w # alfanumeriek teken (a-z, A-Z, 0-9, _), geen newline
\s # een whitespace (spatie, tab, newline), gelijk aan [\t\n\r\f\v]
\D # GEEN cijfer, gelijk aan [^0-9]
\W # GEEN alfanumeriek teken, gelijk aan [^0-9a-zA-Z_]
\S # GEEN whitespace
De betekenis kan verschillen in bepaalde applicaties.
\t # tab
\r # carriage return
\n # line feed
\r\n # nieuwe regel in Windows
\n # nieuwe regel in linux/unix
^ # aan het begin van een regel
$ # aan het einde van een regel
\< # aan het begin van een woord (niet in alle context)
\> # aan het einde van een woord (niet in alle context)
\b # aan het begin of het einde van een woord (begrenzing van een woord)
{n} # exact n keer
{n,} # n of meer keer
{n,m} # tussen n en m keer
Regex-kwantificatoren zoals *
, +
, {n,m}
zijn standaard greedy (hebzuchtig) - ze proberen zoveel mogelijk tekens te matchen. Een voorbeeld.
Tekst: <div>Hello</div><div>World</div>
Patroon: <.*>
Je zou verwachten dat dit <div>
en </div>
apart matcht, maar greedy matching geeft de hele tekst. Het matcht vanaf de eerste <
tot de laatste >
- zoveel mogelijk!
Voor Non-greedy (Lui) matching voeg je een ?
toe na de kwantificator om zo weinig mogelijk te matchen.
Patroon: <.*?>
Dit patroon zorgt voor vier matches in de tekst: <div>
, </div>
, <div>
en </div>
.
Testen van je regex is daarom erg belangrijk omdat het greedy gedrag voor onverwachte resultaten kan zorgen.
Tekst: <b>vet</b> en <i>cursief</i>
Greedy <.*> : <b>vet</b> en <i>cursief</i> (alles!)
Non-greedy <.*?>: <b>, </b>, <i>, </i> (elke tag apart)
Tekst: "eerste" en "tweede" string
Greedy ".*" : "eerste" en "tweede" (van eerste " tot laatste ")
Non-greedy ".*?": "eerste", "tweede" (elke string apart)
Tekst: abc123def456ghi
Greedy \d+.*\d+ : 123def456 (van eerste cijfer tot laatste cijfer)
Non-greedy \d+.*?\d+: 123def456 (kortste pad tussen cijfergroepen)
Greedy gebruiken voor:
Hele zinnen of regels matchen
Wanneer je echt alles tussen twee punten wilt
Non-greedy gebruiken voor:
HTML/XML tags parsen
Strings tussen aanhalingstekens
Wanneer je specifieke, korte matches wilt
[1-9][0-9]{3}\s?[A-Z]{2}
De \s?
betekent dat er optioneel (0 of 1 keer) een whitespace-teken (spatie, tab, …) mag voorkomen tussen de vier cijfers en de twee letters. Beide varianten worden veel gebruikt.
Matcht: “1234AB”, “1234 AB”
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
Matcht: “jan@example.com”, “test.email+tag@domain.co.uk”
0[1-9][0-9]{8}
Matcht: “0612345678”, “0201234567”
[0-3][0-9]-[0-1][0-9]-[0-9]{4}
Matcht: “15-03-2024”, “01-12-2023”
https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
Matcht: “http://google.com”, “https://www.example.org”
De meeste programmeertalen en teksteditors ondersteunen regex voor zoeken en vervangen.
Door delen van je regex tussen haakjes ()
te zetten wordt dit deel als een groep gekarakteriseerd. Regex “onthoudt” wat er in die groep gematcht is. Elke groep krijgt automatisch een backreference nummer (1, 2, 3, etc.).
Tekst: 18-06-2025
Zoekpatroon: (\d{2})-(\d{2})-(\d{4})
Dit matcht een datum en onthoudt dag, maand en jaar als aparte groepen:
Na het matchen kun je de opgeslagen groepen gebruiken in je vervangpatroon. Zo zal het vervangpatroon $3/$2/$1
opleveren: 2025/06/18
Welk symbool ($
, \
, …) gebruikt wordt om naar het groepsnummer te verwijzen hangt van de gebruikte applicatie.
Voorbeeld 1 Vervang de datum “18-06-2025” door “2025/06/18”.
Zoekpatroon: (\d{2})-(\d{2})-(\d{4})
Vervangpatroon: $3/$2/$1
of in sommige programma’s \3/\2/\1
(\w+)\s+(\w+)
(voornaam achternaam)$2, $1
(wordt: achternaam, voornaam)Er zijn veel online tools om regex te testen en te oefenen. Hier zijn enkele populaire:
pythex - voor het testen van Python regular expressions
Er zijn verschillende manieren om via regex in R naar patronen in een tekstvector te zoeken.
RStudio gebruikt “POSIX Basic Regular Expressions” bij het gebruik van Find in files
omdat deze functionaliteit gebruik maakt van grep
.
Zie ook: R 4 data science en RegExplain (Rstudio addinn voor regular expressions)
Handig is het gebruik van package stringr dat met functie regex()
ondersteuning voor regular expressions biedt.
grep()
is een basis-R-functie en retourneert een vector die de indices van de overeenkomsten bevat.
Om de waarde te retourneren in plaats van de index moet je parameter value = TRUE
opnemen.
grep()
is hoofdlettergevoelig. Deze kun je uitzetten met argument ignore.case=TRUE
.
Bij zoek (en vervang) acties krijg je een dialoogvenster met daarin de keuze voor de Zoekmodus: Normaal (default), Uitgebreid, Reguliere expressie. Deze laatste gebruikt de Boost-engine voor reguliere expressies om zoek- en vervangacties uit te voeren, zie uitleg.
Enkele voorbeelden bij het werken met Quarto en Markdown documenten.
Voorbeeld 2 Vervang [mijntekst]{.term}
door **mijntekst**
Zoekpatroon: (\[)([\w\s]+)(\]){\.term}
Vervangpatroon: **$2**
RegexBuddy is een krachtige tool voor het ontwikkelen, testen en gebruiken van regex. Het biedt een gebruikersvriendelijke interface en uitgebreide documentatie.
Zie ook Regular-Expressions.info
RegexMagic helpt bij het automatisch genereren van regex-patronen op basis van voorbeelden. Je geeft voorbeelden van de tekst die je wilt matchen en RegexMagic genereert het patroon voor je.