Numero generale delle catture nelle espressioni regolari PHP

Consideriamo la seguente situazione. Supponiamo di avere una variabile con un anno che può variare da 1990 a 2099. Supponiamo di voler ottenere le ultime due cifre dell'anno in un gruppo di cattura. Scriviamo l'espressione regolare corrispondente:

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

Tuttavia, qui ci aspetta un inconveniente. Il fatto è che per gli anni del secolo scorso le due cifre finiranno nel primo gruppo, mentre per gli anni del secolo successivo - nel secondo. Vediamo con degli esempi.

Ecco la prima variante:

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

Ed ecco la seconda variante:

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

Supponiamo ora di voler salvare le cifre trovate dell'anno in una variabile. Ci troveremo di fronte a un problema, poiché non sappiamo esattamente con quale chiave prelevare i dati dal gruppo di cattura:

php<?php
  $year = $res[1]; // serve la chiave 1 o 2
?>

Si potrebbe risolvere il problema con una condizione:

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

Tuttavia, esiste una soluzione più semplice. Si può usare il costrutto speciale (?| ). Tutti i gruppi di cattura al suo interno avranno lo stesso numero.

Correggiamo la nostra espressione regolare

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

E ora il nostro anno sarà sicuramente nel gruppo di cattura numero uno:

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

Sono date stringhe con date, in cui l'anno può variare da 1990 a 2099:

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

Per ogni data, mettete il giorno nel primo gruppo di cattura, il mese nel secondo, e le ultime due cifre dell'anno - nel terzo.