Tanda Kurung Bukan Penangkap dalam Regex PHP
Tanda kurung () melakukan dua fungsi -
pengelompokan aksara dan fungsi tangkapan (capturing group). Tetapi
bagaimana jika kita hanya perlu mengelompokkan,
tetapi tidak mahu menangkapnya?
Untuk menyelesaikan masalah ini, diciptakan
tanda kurung bukan penangkap (?: )
- ia mengelompokkan, tetapi tidak menangkap ke dalam kumpulan.
Contoh
Dalam contoh berikut, tanda kurung pertama kita perlukan untuk pengelompokan, dan tanda kurung kedua - untuk tangkapan. Walau bagaimanapun, kedua-dua tanda kurung tersebut menyimpan data ke dalam kumpulan tangkapan:
<?php
$str = 'abab123';
$reg = '#(ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
Hasilnya, dalam kumpulan tangkapan kita akan terdapat yang berikut:
<?php
var_dump($res[0]); // akan output 'abab123'
var_dump($res[1]); // akan output 'ab'
var_dump($res[2]); // akan output '123'
?>
Contoh
Mari kita ubah supaya pasangan tanda kurung pertama hanya mengelompokkan, tetapi tidak menangkap ke dalam kumpulan:
<?php
$str = 'abab123';
$reg = '#(?:ab)+([1-9]+)#';
preg_match_all($reg, $str, $res);
?>
Hasilnya, dalam kumpulan tangkapan pertama akan terdapat nombor kita:
<?php
var_dump($res[1]); // akan output '123'
?>
Masalah Praktikal
Diberi substring yang dipisahkan kepada dua bahagian
oleh sebarang bilangan pasangan $@:
<?php
$str = 'aaa$@bbb aaa$@$@bbb aaa$@$@$@bbb';
?>
Cari setiap substring tersebut dan untuk setiap substring yang ditemui, letakkan dalam kumpulan tangkapan pertama apa yang berada sebelum pemisah, dan dalam kumpulan tangkapan kedua - apa yang berada selepas pemisah.