การแทนที่ด้วย Callback ผ่าน Regular Expressions ใน PHP
สมมติว่าเรามีสตริงต่อไปนี้:
<?php
$str = '2+3= 3+5= 7+8=';
?>
สมมติว่าเราต้องการค้นหาโครงสร้างทั้งหมดในรูปแบบ ตัวเลข+ตัวเลข= และทำให้ หลังเครื่องหมายเท่ากับปรากฏผลลัพธ์ของการบวก
สำหรับการแก้ไขปัญหาประเภทนี้ สะดวกที่จะใช้
ฟังก์ชัน preg_replace_callback ซึ่ง
ทำงานคล้ายกับฟังก์ชัน preg_replace
- ค้นหาและแทนที่โดยใช้นิพจน์ทั่วไป (Regular Expression)
แต่อนุญาตให้ดำเนินการจัดการเพิ่มเติม
กับชิ้นส่วนที่พบได้
พารามิเตอร์แรก ฟังก์ชันรับนิพจน์ทั่วไป (RegEx) พารามิเตอร์ที่สอง - สิ่งที่จะแทนที่ พารามิเตอร์ที่สาม - สตริง ที่กำลังดำเนินการแทนที่
ในกรณีนี้ ควรส่งฟังก์ชัน Callback ไปยังพารามิเตอร์ที่สอง ซึ่งจะถูกเรียกสำหรับ การจับคู่ที่พบแต่ละครั้ง
พารามิเตอร์แรกของ Callback ควรระบุ ตัวแปรที่จะเก็บค่าที่พบ ตัวแปรนี้จะเป็นอาร์เรย์ ของกลุ่มที่จับได้ (Capture Groups)
ลองปฏิบัติกัน เขียนโค้ด ที่จับสตริงย่อยของเรา ในขณะเดียวกัน ก็วางตัวเลขแรกไว้ในกลุ่มที่ 1 และตัวเลขที่สอง - ไว้ในกลุ่มที่ 2:
<?php
$str = '2+3= 3+5= 7+8=';
preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
var_dump($match);
}, $str);
?>
ผลลัพธ์ var_dump ของเรา
จะทำงานสามครั้ง โดยจะแสดงผลดังต่อไปนี้ทีละอัน:
['2+3=', '2', '3']
['3+5=', '3', '5']
['7+8=', '7', '7']
ไปต่อ แต่ละการจับคู่จะถูกแทนที่
ด้วยสิ่งใดก็ตามที่ Callback ส่งคืนผ่าน return
ลองตัวอย่างโดยการแทนที่แต่ละสตริงย่อยที่ค้นหา
ด้วยเครื่องหมาย '!':
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return '!';
}, $str);
echo $res; // จะแสดง '! ! !'
?>
และตอนนี้ ให้แทนที่แต่ละสตริงย่อยด้วยผลรวม ของคู่ตัวเลขในนั้น:
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return $match[1] + $match[2];
}, $str);
echo $res; // จะแสดง '5 8 13'
?>
ปรากฏว่า งานของเราเกือบจะเสร็จสมบูรณ์แล้ว เหลือเพียงทำให้ก่อนผลรวม ของตัวเลขยังคงมีสตริงย่อยที่ค้นหาอยู่ สำหรับสิ่งนี้ ให้ใส่เนื้อหาของกลุ่มที่ 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; // จะแสดง '2+3=5 3+5=8 7+8=13'
?>
กำหนดสตริง:
<?php
$str = 'The numbers are 3, 7 and 12';
?>
แทนที่ตัวเลขทั้งหมดในสตริงด้วยกำลังสองของมัน
ผลลัพธ์ที่คาดหวัง:
'The numbers are 9, 49 and 144'
กำหนดสตริง:
<?php
$str = '2023-01-15 2022-12-31 2024-05-20';
?>
แปลงวันที่ทั้งหมดเป็นรูปแบบ วัน.เดือน.ปี
กำหนดสตริง:
<?php
$str = 'Costs: $15, $20, $100';
?>
เพิ่มราคาทั้งหมดขึ้น 10%