กลุ่มจับชื่อใน Regex ของ PHP

สมมติว่าเราต้องการใช้ preg_match เพื่อแยกวันที่ออกเป็นวัน เดือน และปี เราจะใช้ กลุ่มจับสำหรับงานนี้:

php<?php
  $str = '2025-10-29';
  $reg = '#(\d{4})-(\d{2})-(\d{2})#';
  
  preg_match($reg, $str, $match);
  var_dump($match); // จะแสดงผล ['2025-10-29', '2025', '10', '29']
?>

อย่างที่คุณเห็น ในผลลัพธ์เราได้อาร์เรย์ ซึ่งในองค์ประกอบที่ศูนย์จะเป็นวันที่ทั้งหมด ในองค์ประกอบแรก - ปี ที่สอง - เดือน ที่สาม - วัน

อย่างไรก็ตาม บางครั้งมันก็สะดวกที่จะได้เนื้อหาของ กลุ่มจับในรูปแบบของอาร์เรย์เชื่อมโยง นั่นคือ ในกรณีของเรา คงจะดีถ้าได้ อาร์เรย์แบบนี้:

php[
  'year'  => '2025',
  'month' => '10',
  'day'   => '29'
]

สำหรับสิ่งนี้ใน Regex มีไวยากรณ์พิเศษ นี่คือ: (?<name>pattern), โดยที่ pattern คือ Regex และ name คือชื่อของกลุ่มจับ

ลองเขียน Regex สำหรับวันที่ของเราใหม่ โดยใช้กลุ่มจับชื่อ:

php<?php
  $str = '2025-10-29';
  $reg = '#(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})#';
  
  preg_match($reg, $str, $match);
  var_dump($match);
?>

ผลลัพธ์ที่ได้คืออาร์เรย์เชื่อมโยง ซึ่งคีย์จะเป็นชื่อของกลุ่มจับ และค่า - คือสิ่งที่ถูกจับไว้ในนั้น:

php[
  'year'  => '2025',
  'month' => '10',
  'day'   => '29',
]

ในความเป็นจริง ในอาร์เรย์ผลลัพธ์ค่า ของกลุ่มจับจะสามารถเข้าถึงได้ทั้งโดยชื่อและโดยหมายเลขลำดับ นั่นคือ ตัวอย่างเช่น ปีจะสามารถเข้าถึงได้โดยคีย์ 'year' และโดยหมายเลข 1 เดือน - โดยคีย์ 'month' และโดยหมายเลข 2 และต่อไปเรื่อยๆ:

php[
  'year'  => '2025',
  'month' => '10',
  'day'   => '29',
  
  1       => '2025',
  2       => '10',
  3       => '29'
]

กลุ่มจับชื่อที่อธิบายไว้ยังมีไวยากรณ์ทางเลือกอีกสองสามแบบ: (?P<name>pattern) และ (?'name'pattern)

Задание 1

กำหนดสตริงเวลาดังนี้:

php<?php
  $str = '12:59:59';
?>

จับชั่วโมง นาที และวินาทีไว้ใน กลุ่มจับชื่อที่แยกจากกัน

Задание 2

เขียนฟังก์ชันที่ในอาร์เรย์ผลลัพธ์ จะลบกลุ่มจับที่เป็นตัวเลขทั้งหมดออก เหลือไว้ เฉพาะกลุ่มจับชื่อ