先来个最简单的正则表达式递归
字符串 :abc123dsf654wre485wer652
传统作法:\w{3}\d{3}\w{3}\d{3}\w{3}\d{3}\w{3}\d{3}
递归做法:(\w{3}\d{3}|(?R))*
当然这个例子不太合适, 只能说明正则的递归用法罢了
其实还可以用(\w{3}\d{3})*
你看递归的好处, 精悍短少(有力), 传统作法无法比拟.
在网上找了一番正则递归的资料, 最终谷歌了一下, 还是在 PHP 官网上面找到我想要的示例.
- <?PHP
- $string = "some text (aaa(b(c1)(c2)d)e)(test) more text";
- preg_match_all("/\((([^()]*|(?R))*)\)/", $string, $matches);
- echo '<pre>';
- print_r($matches);
- echo '</pre>';
- ?>
看了示例之后, 瞬间明白了, 原理很简单
/\((([^()]*|(?R))*)\)/
为了清晰, 我格式化一下
- /
- \( #看到这里的转义左括号没有? 这里是入口, 意味着这个正则会从左括号开始匹配
- ( #这里是分组用
- (
- [^()]*|(?R) #这里就是递归, 相当于[^()]*|(\((([^()]*| 递归....
- )* #这对括号加上一个星 * 表明, 我要重复递归这件事.
- )
- \)
- /
相对于这行字符串: some text (aaa(b(c1)(c2)d)e)(test) more text
过程是这样的(用 Word 搞了一番):
你看第八步, 是否有疑问?
为什么 "第二个对应右括号" 前面的 d 也被匹配了呢?
答案: 因为正则的第二个星号, 第二个星号做的事情是重复这个星号前面括号的内容, 也就是还没到 "第二个对应右括号" 之前, 这个'd'被星号重复匹配了 .
简而言之就是: 匹配左括号 匹配文字 或者 递归 (这一块吃掉后面的对对括号的内容, 其实我管你递归怎么搞, 你搞完后, 之后的在我这一层级就按我的来) 匹配右括号
来源: https://blog.csdn.net/technofiend/article/details/49906755