PHP正規表現におけるキャプチャグループの共通番号

次の状況を考えてみましょう。変数に年があり、 それは1990から2099まで変化し得るとします。 年の下2桁をキャプチャグループ(カプチャ)で取得したいとします。 対応する正規表現を書きましょう:

php<?php
  $reg = '#19(9\d)|20(\d\d)#';
?>

しかし、ここで1つの不便が待ち構えています。 問題は、20世紀の年の場合、下2桁は最初のキャプチャグループに格納され、 21世紀の年の場合は2番目のキャプチャグループに格納されることです。 例を見てみましょう。

最初のケースです:

php<?php
  $str = '1991';
  preg_match($reg, $str, $res);
  var_dump($res); // [1 => '91']
?>

次に2番目のケースです:

php<?php
  $str = '2021';
  preg_match($reg, $str, $res);
  var_dump($res); // [2 => '21']
?>

ここで、見つけた年の数字を変数に代入したいとします。 キャプチャグループからどのキーでデータを取得すべきか正確には分からないため、 問題に直面します:

php<?php
  $year = $res[1]; // キーは1か2のどちらかが必要
?>

条件分岐で問題を解決できます:

php<?php
  if (!empty($res[1])){
    $year = $res[1];
  } else{
    $year = $res[2];
  }
?>

しかし、もっと簡単な解決策があります。 特別な構文(?| )を使用できます。 この中にあるすべてのキャプチャグループは同じ番号になります。

正規表現を修正してみましょう

php<?php
  $reg = '#(?|19(9\d)|20(\d\d))#';
?>

これで、年は必ず番号1のキャプチャグループに格納されます:

php<?php
  $year = $res[1];
?>
Задание 1

年が1990から2099まで変化する可能性のある 日付を含む文字列が与えられます:

php<?php
  $arr = [
    '31-12-2025',
    '30-11-1995',
    '29-10-1990',
  ];
?>

各日付について、日を1番目のキャプチャグループ、 月を2番目のキャプチャグループ、 年の下2桁を3番目のキャプチャグループに格納してください。