Именувани групи в регулярните изрази на PHP

Да предположим, че с помощта на preg_match искаме да разделим дата на ден, месец и година. Ще използваме за целта групи:

php<?php
  $str = '2025-10-29';
  $reg = '#(\d{4})-(\d{2})-(\d{2})#';
  
  preg_match($reg, $str, $match);
  var_dump($match); // ще изведе ['2025-10-29', '2025', '10', '29']
?>

Както виждате, в резултата получаваме масив, в който в нулевия елемент ще бъде цялата дата, в първия - годината, във втория - месецът, в третия - денят.

Понякога обаче би било удобно да получим съдържанието на групите под формата на асоциативен масив. Тоест в нашия случай би било добре да получим ето такъв масив:

php[
  'year'  => '2025',
  'month' => '10',
  'day'   => '29'
]

За целта в регулярните изрази съществува специален синтаксис. Ето го: (?<name>pattern), където pattern - това е регулярният израз, а name - това е името на групата.

Нека пренапишем нашия регулярен израз за дата чрез именувани групи:

php<?php
  $str = '2025-10-29';
  $reg = '#(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})#';
  
  preg_match($reg, $str, $match);
  var_dump($match);
?>

В резултат ще получим асоциативен масив, в който ключовете ще бъдат имената на групите, а стойностите - това, което е попаднало в тях:

php[
  'year'  => '2025',
  'month' => '10',
  'day'   => '29',
]

Всъщност в масива с резултата стойностите на групите ще бъдат достъпни както по име, така и по пореден номер. Тоест, например, година ще бъде достъпна по ключ 'year' и по номер 1, месецът - по ключ 'month' и по номер 2 и така нататък:

php[
  'year'  => '2025',
  'month' => '10',
  'day'   => '29',
  
  1       => '2025',
  2       => '10',
  3       => '29'
]

Описaните именувани групи имат още няколко алтернативни синтаксиса: (?P<name>pattern) и (?'name'pattern).

Задание 1

Даден е низ с време:

php<?php
  $str = '12:59:59';
?>

Поставете часовете, минутите и секундите в отделни именувани групи.

Задание 2

Напишете функция, която в масива с резултата да изтрие всички номерирани групи, оставяйки само именуваните.