PHP正则之递归匹配

我记得早前有同事问, 正则是否能处理括号配对的正则匹配.
比如, 对于如下的待匹配的字符串:

   ((()))

就是一个括号配对的字符串. 而对于如下的待匹配字符串:

   ((()

则不是一个括号配对的字符串.
在以前, 这种情况, 正则无法处理, 最多只能处理固定层数的递归, 而无法处理无线递归的情况… 而在perl 5.6以后, 引入了一个新的特性: Recursive patterns, 使得这种需求可以被正确的处理.
Recursive pattern引入了一个新的符号(?R), 这个符号可以表示: 正则模式本身, 比如:

    #1(?R)*#

我们来仔细看一下, 这个正则, 首先它匹配数字”1″, 然后(?R)*表示, 正则式本身, 也就是说, 可以认为是:

    #1(正则本身(正则本身).....)*#

于是, 对于文章开头说到的情况:”括号配对”, 可以写下如下的正则式:

     #\((?R)*\)#

就可以正确处理.
这里提醒一下, 用的时候, 要注意一定要给递归一个截至条件, 比如如果上面的例子写成:

   #1(?R)#

那么, 就不会正常工作, 因为这个展开以后表示要匹配无限多个”1″, 所以在上面的例子中, 写作了(?R)*, 让它可以有一个截止的条件(可以为0个).
另外, 这个新特性也支持序号引用(?index), 比如:

     #(1)(2)(3)(?3)(?2)(?1)#

表示匹配, 123321.
如果想更多的了解这个新特性, 可以参看: http://www.php.net/manual/en/regexp.reference.recursive.php
感谢windy, 和shiwei提供的帮助

 收藏 (0) 打赏

您可以选择一种方式赞助本站

支付宝扫一扫赞助

微信钱包扫描赞助

除特别注明外,本站所有文章均基于CC-BY-NC-SA 4.0原创,转载请注明出处。
文章名称:《PHP正则之递归匹配》
文章链接:https://www.lbyxlz.com/php%e6%ad%a3%e5%88%99%e4%b9%8b%e9%80%92%e5%bd%92%e5%8c%b9%e9%85%8d/
分享到: 生成海报

评论 抢沙发

  • QQ号
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
切换注册

登录

点击按钮进行验证

忘记密码 ?

您也可以使用第三方帐号快捷登录

切换登录

注册

我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活