Yleinen taskunumerointi PHP:n säännöllisissä lausekkeissa
Tarkastellaan seuraavaa tilannetta. Oletetaan, että meillä
on muuttuja vuodelle, joka voi vaihdella
välillä 1990 - 2099.
Oletetaan, että haluamme saada vuoden kaksi viimeistä numeroa
taskuun. Kirjoitetaan vastaava säännöllinen lauseke:
<?php
$reg = '#19(9\d)|20(\d\d)#';
?>
Tässä odottaa kuitenkin yksi epämukavuus. Asia on niin, että menneen vuosisadan vuosille kaksi numeroa menevät ensimmäiseen taskuun, kun taas nykyisen vuosisadan vuosille - toiseen. Katsotaan esimerkein.
Tässä on ensimmäinen vaihtoehto:
<?php
$str = '1991';
preg_match($reg, $str, $res);
var_dump($res); // [1 => '91']
?>
Ja tässä toinen vaihtoehto:
<?php
$str = '2021';
preg_match($reg, $str, $res);
var_dump($res); // [2 => '21']
?>
Oletetaan nyt, että haluamme tallentaa löydetyt vuoden numerot muuttujaan. Meitä odottaa ongelma, sillä emme tiedä tarkalleen, millä avaimella ottaa tiedot taskusta:
<?php
$year = $res[1]; // tarvitaan avain joko 1 tai 2
?>
Ongelman voi ratkaista ehdollisen lauseen avulla:
<?php
if (!empty($res[1])){
$year = $res[1];
} else{
$year = $res[2];
}
?>
On kuitenkin olemassa yksinkertaisempi ratkaisu. Voidaan käyttää
erikoiskomentoa (?| ). Kaikki taskut,
jotka sijaitsevat sen sisällä, saavat
yhden numeron.
Korjataan säännöllinen lausekkeemme
<?php
$reg = '#(?|19(9\d)|20(\d\d))#';
?>
Ja nyt vuodemme on varmasti taskussa numero yksi:
<?php
$year = $res[1];
?>
Annettuina ovat päivämääriä sisältävät merkkijonot, joissa vuosi voi
vaihdella välillä 1990 - 2099:
<?php
$arr = [
'31-12-2025',
'30-11-1995',
'29-10-1990',
];
?>
Tallenna jokaisesta päivämäärästä päivä ensimmäiseen taskuun, kuukausi toiseen ja vuoden kaksi viimeistä numeroa - kolmanteen.