怎么在PHP中使用递归正则表达式

介绍

这篇文章给大家介绍怎么在PHP中使用递归正则表达式,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

什么时候会用到递归正则表达式呢?当然是待匹配的字串中递归地出现某种模式时(貌似废话)。最经典的例子,就是递归正则处理嵌套括号的问题了。例子如下。

假设你的文本中包含了正确配对的嵌套括号。括号的深度可以是无限层。你想捕获这样的括号组。

代码如下:


& lt; ?php
$ string=耙恍┪谋?d) e (b (c))更text";
如果(preg_match (“/\ (((^ ()) + | (R)) * \)/?字符串,美元$ matches)) {
回声“& lt; pre>“;print_r ($ matches);回声“& lt;/pre>“;
}
?比;


结果是:

代码如下:


数组
(
[0]=比;(d) e (b (c))
[1]=比;e
)


可见,我们所需要的文,本已经捕获到$ matches[0]中了。

原理

现在思考原理。

上面的正则表达式中的关键点是R (?)。(? R)的作用就是递归地替换它所在的整条正则表达式。在每次迭代时,PHP语法分析器都会将(? R)替换为“\ (((^ ())+ | (R)) * \)”。
因此,具体到上述的例子,其正则表达式等价于:

代码如下:


“/\ (((^ ()) + | \ (((^ ()) + | \ (((^ ()] +) * \)) * \)) * \)/?


但是上面的代码只适合深度为3层的括号。对于未知深度的括号嵌套,就只好使用这种正则了:

代码如下:


“/\ (((^ ()) + | (R)) * \)/?


它不但能够匹配无限深度,还简化了正则表达式的语法。功能强大,语法简洁。

现在来细看一下“/\ (((^ ())+ | (R)) * \)/笆窃跹ヅ洹?d) e (b (c))“的:

, (c)“这部分被正则式“\ (((^ ()]+)* \)“;匹配。请注意,(c)其实就相当于整个递归的一个缩影,麻雀虽小五脏俱全,因此它用到了整个正则表达式。
换言之,下一步中的(c),可以使用(? R)来匹配。

(b (c) d)的匹配过程为:
“\(“匹配“(“;
“[^()) +“匹配“b";
(? R)匹配“(c)“;
“[^()) +“匹配“d";
“\)“匹配“)”。

根据上面的匹配原理,不难理解为什么数组的第2个元素$ matches[1]与& # 39;e # 39;等价。子串& # 39;e # 39;是在最后一次匹配迭代中被捕获。匹配过程中,只有最后一次的捕获结果才会保存到数组中。
关于这个特性,可以自行尝试一下,看看使用正则式([a - z] +[0 - 9] +) +来匹配字串abc123xyz890,其捕获结果1美元是什么。注意,其结果与左最长的原理并不冲突。

如果我们只需要捕获$ matches[0],可以这样做:

代码如下:


& lt; ?php
$ string=耙恍┪谋?d) e (b (c))更text";
如果(preg_match (“/((?: [^ ()) + | (R)) *)/?字符串,美元$ matches))
{
回声“& lt; pre>“;print_r ($ matches);回声“& lt;/pre>“;
}
?比;
产生的结果相同:

数组
(
[0]=比;(d) e (b (c))
)


所做的改动是捕获括号()改为非捕获捕获括号(?)了。

还可以进一步完善为:

代码如下:


& lt; ?php
$ string=耙恍┪谋?d) e (b (c))更text";
如果(preg_match(“/((?祝辞[^ ())+ | (R)) *)/?字符串,美元$ matches))
{
回声“& lt; pre>“;print_r ($ matches);回声“& lt;/pre>“;
}
?比;

关于怎么在PHP中使用递归正则表达式就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看的到。

怎么在PHP中使用递归正则表达式