PHP正規表現におけるキャプチャグループの共通番号
次の状況を考えてみましょう。変数に年があり、
それは1990から2099まで変化し得るとします。
年の下2桁をキャプチャグループ(カプチャ)で取得したいとします。
対応する正規表現を書きましょう:
<?php
$reg = '#19(9\d)|20(\d\d)#';
?>
しかし、ここで1つの不便が待ち構えています。 問題は、20世紀の年の場合、下2桁は最初のキャプチャグループに格納され、 21世紀の年の場合は2番目のキャプチャグループに格納されることです。 例を見てみましょう。
最初のケースです:
<?php
$str = '1991';
preg_match($reg, $str, $res);
var_dump($res); // [1 => '91']
?>
次に2番目のケースです:
<?php
$str = '2021';
preg_match($reg, $str, $res);
var_dump($res); // [2 => '21']
?>
ここで、見つけた年の数字を変数に代入したいとします。 キャプチャグループからどのキーでデータを取得すべきか正確には分からないため、 問題に直面します:
<?php
$year = $res[1]; // キーは1か2のどちらかが必要
?>
条件分岐で問題を解決できます:
<?php
if (!empty($res[1])){
$year = $res[1];
} else{
$year = $res[2];
}
?>
しかし、もっと簡単な解決策があります。
特別な構文(?| )を使用できます。
この中にあるすべてのキャプチャグループは同じ番号になります。
正規表現を修正してみましょう
<?php
$reg = '#(?|19(9\d)|20(\d\d))#';
?>
これで、年は必ず番号1のキャプチャグループに格納されます:
<?php
$year = $res[1];
?>
年が1990から2099まで変化する可能性のある
日付を含む文字列が与えられます:
<?php
$arr = [
'31-12-2025',
'30-11-1995',
'29-10-1990',
];
?>
各日付について、日を1番目のキャプチャグループ、 月を2番目のキャプチャグループ、 年の下2桁を3番目のキャプチャグループに格納してください。