วงเล็บไม่จับกลุ่มใน Regular Expressions ของ PHP
วงเล็บ () ทำหน้าที่สองอย่างคือ
การจัดกลุ่มอักขระและการทำหน้าที่เป็น capture group (การจับกลุ่มและเก็บค่า)
แล้วถ้าเราต้องการจัดกลุ่ม
แต่ไม่อยากเก็บค่าล่ะ?
เพื่อแก้ปัญหานี้จึงมี
วงเล็บไม่จับกลุ่ม (?: ) พิเศษขึ้นมา
- มันจัดกลุ่ม แต่ไม่เก็บค่าไว้ใน capture group
ตัวอย่าง
ในตัวอย่างต่อไปนี้ วงเล็บชุดแรกเราต้องการ เพื่อการจัดกลุ่ม และชุดที่สองสำหรับ capture group อย่างไรก็ตาม วงเล็บทั้งสองแบบเก็บข้อมูล ไว้ใน capture group:
<?php
$str = 'abab123';
$reg = '#(ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
ผลลัพธ์ใน capture groups ของเราจะได้ดังนี้:
<?php
var_dump($res[0]); // จะได้ 'abab123'
var_dump($res[1]); // จะได้ 'ab'
var_dump($res[2]); // จะได้ '123'
?>
ตัวอย่าง
ลองทำให้วงเล็บคู่แรกทำหน้าที่เพียง จัดกลุ่มเท่านั้น แต่ไม่เก็บค่า:
<?php
$str = 'abab123';
$reg = '#(?:ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
ผลลัพธ์ใน capture group แรกจะเป็นตัวเลขของเรา:
<?php
var_dump($res[1]); // จะได้ '123'
?>
แบบฝึกหัด
ให้สตริงย่อยที่ถูกแบ่งออกเป็นสองส่วน
ด้วยคู่ของ $@ จำนวนเท่าใดก็ได้:
<?php
$str = 'aaa$@bbb aaa$@$@bbb aaa$@$@$@bbb';
?>
จงหาสตริงย่อยแต่ละอันที่ตรงเงื่อนไข และสำหรับแต่ละ สตริงที่พบ ให้เก็บค่าใน capture group แรก เป็นส่วนที่อยู่ก่อนตัวคั่น และใน capture group ที่สอง เป็นส่วนที่อยู่หลังตัวคั่น