今天遇到了常规匹配的问题,突然转到了“捕获组”的概念上,手册里也略有通过。百度无意中求助于C#和Java中常规抓取组的特殊用法,搜索关键词在PHP中时没有相关内容。我自己尝试了一下,发现在PHP中也是可行的,所以总结一下,在分享的同时,也希望大神和细心的学习者能够发现我理解中的问题。
什么是捕获组
我们先来看看PHP的正则匹配函数
int preg _ match的前两项(string $pattern,string $ subject [,array $ matches [,int $ flags=0 [,int $ offset=0]]是常用的,$pattern是常规匹配模式,$string是要匹配的字符串。
Array$match是一个数组,表示匹配结果将被写入$match。
Int $flags如果传递了此标志,则每次返回时都会附加一个字符串偏移量(相对于目标字符串的偏移量)。
Int $offset用于指定从未知目标字符串中搜索(以字节为单位)。
让我们主要看看$match的价值会是什么:
$ mode='/a=( d)b=( d)c=( d)/';$ str=' * * a=4b=98c=56 * *$res=preg_match($mode,$str,$ match);var _ dump($ match);结果如下:
array(size=4)=string ' a=4b=98c=56 '(长度=11)=string' 4 '(长度=1)=string' 98 '(长度=2)=string' 56 '(长度=2)现在我们知道什么是捕获组了,捕获组就是正则表达式。
PHP会给它编号,从1开始。至于为什么以1开头,是因为PHP将匹配的完整字符串编号为0。
如果有多个括号或嵌套括号,请按照左侧括号出现的顺序对它们进行编号,如图所示:
按照图中的匹配模式匹配时,捕捉组的123号为红、绿、蓝。
忽略并命名捕获组
我们还可以通过添加?
$mode='/a=(d )b=(? d)c=( d)/';
这样,匹配结果将变成:
array(size=3)=string ' a=4b=98c=56 '(length=11)=string ' 4 '(length=1)=string ' 56 '(length=2)当然,我们也可以在括号内给它一个唯一的名称。
命名子组可以接受(?姓名),(?名称')和(?Pname)语法。仅接受以前的版本(?Pname)语法。
例如:$mode='/a=(d )b=(?psec d)c=( d)/';
使用时,结果是:
数组(大小=5)=字符串' a=4b=98c=56 '(长度=11)=字符串' 4 '(长度=1)' sec'=字符串' 98 '(长度=2)=字符串' 98 '(长度=2)=字符串' 56 '
捕获组的反向引用
当我们使用preg_replace()函数进行常规替换时,我们也可以使用n或$n来引用第n个捕获组。
$ mode='/a=( d)b=( d)c=( d)/';$ str=' * * a=4b=98c=56 * *$ RP=' 1/$ 2/ 3/';echo preg_replace($mode,$rp,$ str);//**4/98/56/**1表示捕获组1(4),$2表示捕获组2 (98), 3表示捕获组3(56)。
非捕获组的使用:
为什么叫非捕获组?这是因为它们具有捕获组的特性,这些组在匹配模式的()中。但是,匹配时,PHP不会对它们进行分组。它们只会影响匹配结果,不会作为结果输出。
/d(?=xxx)匹配“后跟一个xxx”。
注意格式:只能放在匹配的模式字符串之后!
例如:
$pattern='/d(?=ABC)/';$ str=' ab36abc8eg$res=preg_match($pattern,$str,$ match);var _ dump($ match);//6匹配6,因为它是唯一后跟abc的数字。
(?=XXX)/d匹配"前面是xxx的一个数字"
注意格式:只能放在匹配的模式字符串之前!
例如:
$pattern='/(?=ABC) d/';$ str=' ab36abc8eg$res=preg_match($pattern,$str,$ match);var _ dump($ match);//8匹配8,因为它是唯一后跟abc的数字。
还有(?=xxx()?=xxx)相对(?=xxx()?=xxx)他们添加了非运算符“!”之前=
意思是一个前面/后面没有xxx的字符串,所以这里就不举例了。
以上关于PHP正则化中捕获组和非捕获组的文章,都是边肖分享给大家的内容,希望能给大家一个参考,多多支持我们。