Thay thế bằng callback thông qua biểu thức chính quy trong PHP
Giả sử chúng ta có chuỗi sau:
<?php
$str = '2+3= 3+5= 7+8=';
?>
Giả sử chúng ta cần tìm tất cả các cấu trúc dạng số+số= và làm sao cho sau dấu bằng xuất hiện kết quả phép cộng.
Để giải quyết nhiệm vụ tương tự, thuận tiện là sử dụng
hàm preg_replace_callback, hàm này
hoạt động tương tự như hàm preg_replace
- tìm và thay thế theo biểu thức chính quy,
nhưng cho phép thực hiện thao tác bổ sung
với các đoạn tìm được.
Tham số đầu tiên hàm nhận biểu thức chính quy, thứ hai - thay bằng cái gì, thứ ba - chuỗi, trong đó thực hiện thay thế.
Đồng thời, vào tham số thứ hai nên truyền hàm callback, sẽ được gọi cho mỗi kết quả khớp tìm được.
Tham số đầu tiên của callback cần chỉ định biến, vào đó cái tìm được sẽ rơi vào. Biến này sẽ đại diện cho mảng các nhóm bắt (capture group) của cái tìm được.
Hãy thử trong thực tế. Viết, mã, mà sẽ bắt các chuỗi con của chúng ta, đồng thời đặt số thứ nhất vào nhóm bắt thứ nhất, còn số thứ hai - vào nhóm thứ hai:
<?php
$str = '2+3= 3+5= 7+8=';
preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
var_dump($match);
}, $str);
?>
Kết quả là var_dump của chúng ta sẽ hoạt động
ba lần, lần lượt xuất ra như sau:
['2+3=', '2', '3']
['3+5=', '3', '5']
['7+8=', '7', '7']
Tiếp tục. Mỗi kết quả khớp sẽ được thay thế
bằng cái mà callback trả về thông qua return.
Hãy ví dụ thay thế mỗi chuỗi con cần tìm
bằng dấu '!':
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return '!';
}, $str);
echo $res; // sẽ xuất ra '! ! !'
?>
Và bây giờ thay thế mỗi chuỗi con bằng tổng của cặp số trong đó:
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return $match[1] + $match[2];
}, $str);
echo $res; // sẽ xuất ra '5 8 13'
?>
Hóa ra, nhiệm vụ của chúng ta gần như đã giải quyết. Còn lại là làm sao để trước tổng số vẫn còn chuỗi con cần tìm. Để làm điều này chúng ta sẽ chèn trước tổng nội dung của nhóm bắt số 0 :
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return $match[0] . ($match[1] + $match[2]);
}, $str);
echo $res; // sẽ xuất ra '2+3=5 3+5=8 7+8=13'
?>
Cho chuỗi:
<?php
$str = 'The numbers are 3, 7 and 12';
?>
Thay thế tất cả số trong chuỗi bằng bình phương của chúng.
Kết quả mong đợi:
'The numbers are 9, 49 and 144'
Cho chuỗi:
<?php
$str = '2023-01-15 2022-12-31 2024-05-20';
?>
Chuyển đổi tất cả ngày tháng sang định dạng ngày.tháng.năm.
Cho chuỗi:
<?php
$str = 'Costs: $15, $20, $100';
?>
Tăng tất cả giá lên 10%.