Regular Expressions
Terug referentie
Zoeken…
Basics
Terugverwijzingen worden gebruikt om overeen te komen met dezelfde tekst die eerder is gekoppeld aan een vastleggroep. Dit helpt zowel bij het hergebruiken van eerdere delen van uw patroon als bij het verzekeren dat twee stukken van een string overeenkomen.
Als u bijvoorbeeld probeert te controleren of een string een cijfer van nul tot negen heeft, een scheidingsteken, zoals koppeltekens, schuine strepen of zelfs spaties, een kleine letter, een ander scheidingsteken, dan nog een cijfer van nul tot negen, kunt u gebruik een regex zoals deze:
[0-9][-/ ][a-z][-/ ][0-9]
Dit zou overeenkomen met 1-a-4
, maar het zou ook overeenkomen met 1-a/4
of 1 a-4
. Als we willen dat de scheidingstekens overeenkomen, kunnen we een opnamegroep en een terugverwijzing gebruiken. De achterreferentie kijkt naar de gevonden match in de aangegeven opnamegroep en zorgt ervoor dat de locatie van de achterreferentie exact overeenkomt.
Met hetzelfde voorbeeld zou de regex worden:
[0-9]([-/ ])[a-z]\1[0-9]
De \1
geeft de eerste vastleggroep in het patroon aan. Met deze kleine verandering komt de regex nu overeen met 1-a-4
of 1 a 4
maar niet 1 a-4
of 1-a/4
.
Het nummer dat u voor uw rugreferentie moet gebruiken, is afhankelijk van de locatie van uw opnamegroep. Het aantal kan variëren van één tot negen en kan worden gevonden door uw opnamegroepen te tellen.
([0-9])([-/ ])[a-z][-/ ]([0-9])
|--1--||--2--| |--3--|
Geneste opnamegroepen veranderen dit aantal enigszins. Je telt eerst de buitenste groep en vervolgens het volgende niveau en gaat door tot je het nest verlaat:
(([0-9])([-/ ]))([a-z])
|--2--||--3--|
|-------1------||--4--|
Dubbelzinnige terugverwijzingen
Probleem: u moet overeenkomen met tekst van een bepaald formaat, bijvoorbeeld:
1-a-0
6/p/0
4 g 0
Dat is een cijfer, een scheidingsteken (een van -
, /
of een spatie), een letter, hetzelfde scheidingsteken en een nul.
Naïeve oplossing: als je de regex aanpast uit het basics-voorbeeld , bedenk je deze regex:
[0-9]([-/ ])[a-z]\10
Maar dat zal waarschijnlijk niet werken. De meeste regex-smaken ondersteunen meer dan negen opnamegroepen, en slechts weinigen zijn slim genoeg om te beseffen dat, aangezien er slechts één opnamegroep is, \10
een terugverwijzing naar groep 1 moet zijn, gevolgd door een letterlijke 0
. De meeste smaken zullen het behandelen als een terugverwijzing naar groep 10. Een paar daarvan vormen een uitzondering omdat er geen groep 10 is; de rest zal gewoon niet overeenkomen.
Er zijn verschillende manieren om dit probleem te voorkomen. Een daarvan is om benoemde groepen (en benoemde backreferences) te gebruiken:
[0-9](?<sep>[-/ ])[a-z]\k<sep>0
Als uw regex-taal dit ondersteunt, kan de notatie \g{n}
(waarbij n
een getal is) het terugverwijzingsnummer tussen accolades plaatsen om het te scheiden van alle cijfers erna:
[0-9]([-/ ])[a-z]\g{1}0
Een andere manier is om uitgebreide regex-opmaak te gebruiken, waarbij de elementen worden gescheiden met onbeduidende witruimte (in Java moet je ontsnappen aan de ruimte tussen haakjes):
(?x) [0-9] ([-/ ]) [a-z] \1 0
Als uw regex-smaak deze functies niet ondersteunt, kunt u onnodige maar onschadelijke syntaxis toevoegen, zoals een niet-vastleggende groep:
[0-9]([-/ ])[a-z](?:\1)0
... of een dummy kwantificator (dit is mogelijk de enige omstandigheid waarin {1}
nuttig is):
[0-9]([-/ ])[a-z]\1{1}0