PHP 정규식에서 공통 캡처 그룹 번호
다음 상황을 생각해봅시다. 변수에
1990년부터 2099년까지
변할 수 있는 연도가 저장되어 있다고 합시다.
연도의 마지막 두 자릿수를 캡처 그룹에
저장하려고 합니다. 해당 정규식을 작성해 봅시다:
<?php
$reg = '#19(9\d)|20(\d\d)#';
?>
그러나 여기에는 불편한 점이 있습니다. 문제는 20세기의 연도에 대한 두 자릿수는 첫 번째 캡처 그룹에 들어가고, 21세기 연도의 두 자릿수는 두 번째 캡처 그룹에 들어간다는 것입니다. 예시를 통해 살펴봅시다.
첫 번째 예시입니다:
<?php
$str = '1991';
preg_match($reg, $str, $res);
var_dump($res); // [1 => '91']
?>
두 번째 예시입니다:
<?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))#';
?>
이제 우리의 연도는 확실히 첫 번째 번호의 캡처 그룹에 들어갑니다:
<?php
$year = $res[1];
?>
연도가 1990년부터 2099년까지
변할 수 있는 날짜 문자열이 주어졌습니다:
<?php
$arr = [
'31-12-2025',
'30-11-1995',
'29-10-1990',
];
?>
각 날짜에 대해, 날짜를 첫 번째 캡처 그룹에, 월을 두 번째 캡처 그룹에, 연도의 마지막 두 자릿수를 세 번째 캡처 그룹에 저장하세요.