วงเล็บไม่จับกลุ่มใน Regular Expressions ของ PHP

วงเล็บ () ทำหน้าที่สองอย่างคือ การจัดกลุ่มอักขระและการทำหน้าที่เป็น capture group (การจับกลุ่มและเก็บค่า) แล้วถ้าเราต้องการจัดกลุ่ม แต่ไม่อยากเก็บค่าล่ะ? เพื่อแก้ปัญหานี้จึงมี วงเล็บไม่จับกลุ่ม (?: ) พิเศษขึ้นมา - มันจัดกลุ่ม แต่ไม่เก็บค่าไว้ใน capture group

ตัวอย่าง

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

php<?php
  $str = 'abab123';
  $reg = '#(ab)+([1-9]+)#';
  preg_match_all($reg, $str, $res);
?>

ผลลัพธ์ใน capture groups ของเราจะได้ดังนี้:

php<?php
  var_dump($res[0]); // จะได้ 'abab123'
  var_dump($res[1]); // จะได้ 'ab'
  var_dump($res[2]); // จะได้ '123'
?>

ตัวอย่าง

ลองทำให้วงเล็บคู่แรกทำหน้าที่เพียง จัดกลุ่มเท่านั้น แต่ไม่เก็บค่า:

php<?php
  $str = 'abab123';
  $reg = '#(?:ab)+([1-9]+)#';
  preg_match_all($reg, $str, $res);
?>

ผลลัพธ์ใน capture group แรกจะเป็นตัวเลขของเรา:

php<?php
  var_dump($res[1]); // จะได้ '123'
?>

แบบฝึกหัด

Задание 1

ให้สตริงย่อยที่ถูกแบ่งออกเป็นสองส่วน ด้วยคู่ของ $@ จำนวนเท่าใดก็ได้:

php<?php
  $str = 'aaa$@bbb aaa$@$@bbb aaa$@$@$@bbb';
?>

จงหาสตริงย่อยแต่ละอันที่ตรงเงื่อนไข และสำหรับแต่ละ สตริงที่พบ ให้เก็บค่าใน capture group แรก เป็นส่วนที่อยู่ก่อนตัวคั่น และใน capture group ที่สอง เป็นส่วนที่อยู่หลังตัวคั่น