การแทนที่ด้วย Callback ผ่าน Regular Expressions ใน PHP

สมมติว่าเรามีสตริงต่อไปนี้:

php<?php
  $str = '2+3= 3+5= 7+8=';
?>

สมมติว่าเราต้องการค้นหาโครงสร้างทั้งหมดในรูปแบบ ตัวเลข+ตัวเลข= และทำให้ หลังเครื่องหมายเท่ากับปรากฏผลลัพธ์ของการบวก

สำหรับการแก้ไขปัญหาประเภทนี้ สะดวกที่จะใช้ ฟังก์ชัน preg_replace_callback ซึ่ง ทำงานคล้ายกับฟังก์ชัน preg_replace - ค้นหาและแทนที่โดยใช้นิพจน์ทั่วไป (Regular Expression) แต่อนุญาตให้ดำเนินการจัดการเพิ่มเติม กับชิ้นส่วนที่พบได้

พารามิเตอร์แรก ฟังก์ชันรับนิพจน์ทั่วไป (RegEx) พารามิเตอร์ที่สอง - สิ่งที่จะแทนที่ พารามิเตอร์ที่สาม - สตริง ที่กำลังดำเนินการแทนที่

ในกรณีนี้ ควรส่งฟังก์ชัน Callback ไปยังพารามิเตอร์ที่สอง ซึ่งจะถูกเรียกสำหรับ การจับคู่ที่พบแต่ละครั้ง

พารามิเตอร์แรกของ Callback ควรระบุ ตัวแปรที่จะเก็บค่าที่พบ ตัวแปรนี้จะเป็นอาร์เรย์ ของกลุ่มที่จับได้ (Capture Groups)

ลองปฏิบัติกัน เขียนโค้ด ที่จับสตริงย่อยของเรา ในขณะเดียวกัน ก็วางตัวเลขแรกไว้ในกลุ่มที่ 1 และตัวเลขที่สอง - ไว้ในกลุ่มที่ 2:

php<?php
  $str = '2+3= 3+5= 7+8=';
  
  preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
    var_dump($match);
  }, $str);
?>

ผลลัพธ์ var_dump ของเรา จะทำงานสามครั้ง โดยจะแสดงผลดังต่อไปนี้ทีละอัน:

php['2+3=', '2', '3']
['3+5=', '3', '5']
['7+8=', '7', '7']

ไปต่อ แต่ละการจับคู่จะถูกแทนที่ ด้วยสิ่งใดก็ตามที่ Callback ส่งคืนผ่าน return ลองตัวอย่างโดยการแทนที่แต่ละสตริงย่อยที่ค้นหา ด้วยเครื่องหมาย '!':

php<?php
  $str = '2+3= 3+5= 7+8=';
  
  $res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
    return '!';
  }, $str);
  
  echo $res; // จะแสดง '! ! !'
?>

และตอนนี้ ให้แทนที่แต่ละสตริงย่อยด้วยผลรวม ของคู่ตัวเลขในนั้น:

php<?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<?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'
?>
Задание 1

กำหนดสตริง:

php<?php
  $str = 'The numbers are 3, 7 and 12';
?>

แทนที่ตัวเลขทั้งหมดในสตริงด้วยกำลังสองของมัน

ผลลัพธ์ที่คาดหวัง:

php'The numbers are 9, 49 and 144'
Задание 2

กำหนดสตริง:

php<?php
  $str = '2023-01-15 2022-12-31 2024-05-20';
?>

แปลงวันที่ทั้งหมดเป็นรูปแบบ วัน.เดือน.ปี

Задание 3

กำหนดสตริง:

php<?php
  $str = 'Costs: $15, $20, $100';
?>

เพิ่มราคาทั้งหมดขึ้น 10%