Totaal aantal capture groepen in PHP regex
Laten we de volgende situatie bekijken. Stel dat we
een variabele hebben met een jaar, dat kan variëren
van 1990 tot 2099.
Stel dat we de laatste twee cijfers van het jaar
in een capture groep willen krijgen. Laten we de bijbehorende regex schrijven:
<?php
$reg = '#19(9\d)|20(\d\d)#';
?>
Hier wacht ons echter een ongemak. Het probleem is dat voor de jaren van de vorige eeuw de twee cijfers in de eerste capture groep terechtkomen, en voor de jaren van de tweede eeuw - in de tweede. Laten we kijken naar voorbeelden.
Hier is de eerste variant:
<?php
$str = '1991';
preg_match($reg, $str, $res);
var_dump($res); // [1 => '91']
?>
En hier is de tweede variant:
<?php
$str = '2021';
preg_match($reg, $str, $res);
var_dump($res); // [2 => '21']
?>
Stel dat we nu de gevonden cijfers van het jaar in een variabele willen opslaan. We krijgen een probleem, omdat we niet precies weten met welke sleutel we de gegevens uit de capture groep moeten halen:
<?php
$year = $res[1]; // sleutel 1 of 2 nodig
?>
Het probleem kan worden opgelost met een voorwaarde:
<?php
if (!empty($res[1])){
$year = $res[1];
} else{
$year = $res[2];
}
?>
Er is echter een eenvoudigere oplossing. Je kunt de
speciale constructie (?| ) gebruiken. Alle capture groepen
die zich erin bevinden, zullen hetzelfde
nummer hebben.
Laten we onze regex corrigeren
<?php
$reg = '#(?|19(9\d)|20(\d\d))#';
?>
En nu zal ons jaar zeker in de capture groep met nummer één staan:
<?php
$year = $res[1];
?>
Gegeven zijn strings met data, waarin het jaar kan
variëren van 1990 tot 2099:
<?php
$arr = [
'31-12-2025',
'30-11-1995',
'29-10-1990',
];
?>
Plaats voor elke datum de dag in de eerste capture groep, de maand in de tweede, en de laatste twee cijfers van het jaar - in de derde.