Tổng số nhóm bắt giữ trong biểu thức chính quy PHP
Hãy xem xét tình huống sau. Giả sử chúng ta có
một biến chứa năm, có thể thay đổi
từ 1990 đến 2099.
Giả sử chúng ta muốn lấy hai chữ số cuối cùng
của năm vào một nhóm bắt giữ. Hãy viết biểu thức chính quy tương ứng:
<?php
$reg = '#19(9\d)|20(\d\d)#';
?>
Tuy nhiên, có một điều bất tiện đang chờ đợi chúng ta ở đây. Vấn đề là đối với các năm của thế kỷ trước, hai chữ số sẽ rơi vào nhóm bắt giữ đầu tiên, còn đối với các năm của thế kỷ tiếp theo - vào nhóm thứ hai. Hãy xem các ví dụ.
Đây là trường hợp đầu tiên:
<?php
$str = '1991';
preg_match($reg, $str, $res);
var_dump($res); // [1 => '91']
?>
Và đây là trường hợp thứ hai:
<?php
$str = '2021';
preg_match($reg, $str, $res);
var_dump($res); // [2 => '21']
?>
Bây giờ giả sử chúng ta muốn lưu các chữ số năm đã tìm được vào một biến. Chúng ta sẽ gặp vấn đề, vì chúng ta không biết chính xác cần lấy dữ liệu từ nhóm bắt giữ bằng khóa nào:
<?php
$year = $res[1]; // cần khóa 1 hoặc 2
?>
Có thể giải quyết vấn đề bằng điều kiện:
<?php
if (!empty($res[1])){
$year = $res[1];
} else{
$year = $res[2];
}
?>
Tuy nhiên, có một giải pháp đơn giản hơn. Có thể sử dụng
chỉ thị đặc biệt (?| ). Tất cả các nhóm bắt giữ
nằm bên trong nó sẽ có cùng
một số.
Hãy sửa biểu thức chính quy của chúng ta
<?php
$reg = '#(?|19(9\d)|20(\d\d))#';
?>
Và bây giờ năm của chúng ta chắc chắn sẽ nằm trong nhóm bắt giữ với số một:
<?php
$year = $res[1];
?>
Cho các chuỗi chứa ngày tháng, trong đó năm có thể
thay đổi từ 1990 đến 2099:
<?php
$arr = [
'31-12-2025',
'30-11-1995',
'29-10-1990',
];
?>
Đối với mỗi ngày, hãy đặt ngày vào nhóm bắt giữ đầu tiên, tháng vào nhóm thứ hai, và hai chữ số cuối cùng của năm - vào nhóm thứ ba.