正则表达的粉丝,嗨。 在下面的代码中,有两个父标签(T1-4和T5-6)和一个子标签(T2-3)。
你如何匹配T1-4? 或者一般来说,你如何匹配父标签?
<?php
$subject = '
{{poo}} # T1
Hello
{{poo}} # T2
Nested 1
{{/poo}} # T3
{{/poo}} # T4
{{poo}} # T5
Bye
{{/poo}} # T6
';
$p = '!{{(\w+)}}(.*){{/\1}}!s'; // matches T1-6, too greedy
$p = '!{{(\w+)}}(.*?){{/\1}}!s'; // matches T1-3, not what I want
$p = '`(?xs) # xtended
{{(\w+)}}
.*?
(?R)? # currently working on this one...
{{/\1}}
`';
preg_replace_callback($p, function($match){
var_dump($match);
}, $subject);
答案 0 :(得分:3)
这可能就是你要找的东西:
$p = '`(?x)
{{(\w+)}}
# ( # you need probably this capture group later
(?>
[^{]++
|
{ (?!{)
|
{{ (?! /? \1 \b) # if needed you can add }} in the lookahead
|
(?R)
)*
# )
{{/\1}}
`';
答案 1 :(得分:3)
答案略有不同:
~ # Delimiter
{{(.*?)}} # Match opening tag and put the name in group 1
(?: # Non-capturing group
(?:(?!{{/?\1}}).)++ # Match anything that's not an opening/closing tag one or more times, no backtracking
| # Or
(?0) # Recurse the whole pattern, same as (?R)
)* # Repeat zero or more times
{{/\1}} # Match closing tag
~xs
我添加了以下修饰符:
x
:自由间隔模式,我们的正则表达式中也有精彩的评论。s
:将换行符与点匹配。