递归正则表达式不匹配模板块 [英] Recursive regex not matching template blocks
问题描述
我试图更多地了解正则表达式,在这种情况下,您可以在正则表达式中进行递归.
I'm trying to understand more about regex and in this case the recursion you can do in a regular expression.
我正在尝试匹配 {foreach $VAR} ... {/foreach}
的嵌套块.但由于某种原因,我的正则表达式不匹配,我不明白为什么.
I'm trying to match a nested block of {foreach $VAR} ... {/foreach}
. But for some reason my regex isn't matching and i don't understand why.
我希望这里的任何人都可以对此有所了解.我对快速正则表达式修复不感兴趣.但实际上更多的是为什么我的正则表达式没有按照我的预期做.究竟发生了什么?
I was hoping anyone here could shed some light on it. I'm not interested in a quick regex fix. But really more as why my regex isn't doing what i expect. What exactly is happening?
这是我的代码:
<?php
$str = 'start of text
{foreach $ABC}
in 1st loop
{foreach $XYZ}
in 2nd loop
{/foreach}
{/foreach}
some other stuff';
if ( preg_match ( '#{foreach \$.*?}((?!foreach)|(?R))*{/foreach}#', $str, $matches ) )
{
print_r($matches);
}
else
{
echo 'No match';
}
这是我的正则表达式的细分,我认为它是如何工作的:
Here is the breakdown of my regex as how i think it's wokring:
{foreach \$ #match literally "{foreach $"
.*?} #followed by any character ending with a '}'
( # start a group
(?!foreach) # match any character, aslong as it's not the sequence 'foreach'
| # otherwise
(?R) # do a recursion
) # end of group
* # match 0 or more times with a backtrace...
{/foreach} # ...backtracing until you find the last {/foreach}
这就是我认为正则表达式的工作方式.但显然情况并非如此.所以我的问题是,我的解释哪里错了?
That's how i think the regex works. But obviously that is not the case. So my question is, where am i wrong in my explanation?
您可以在此处使用此代码:http://codepad.viper-7.com/508V9w
You can play around with this code here: http://codepad.viper-7.com/508V9w
只是为了澄清.
我正在尝试获取每个 foreach
块的内容.所以就我而言:
I'm trying to get the contents of each foreach
block. So in my case:
arr[0] => in 1st loop
{foreach $XYZ}
in 2nd loop
{/foreach}
arr[1] => in 2nd loop
或 -
arr[0] => {foreach $ABC}
in 1st loop
{foreach $XYZ}
in 2nd loop
{/foreach}
{/foreach}
arr[1] => {foreach $XYZ}
in 2nd loop
{/foreach}
哪个都行.
推荐答案
首先,.
确实匹配除 换行符以外的任何东西.为了让它也匹配换行符,你必须设置修饰符 s
.
First of all, the .
does match anything but newlines per default. To have it match newlines as well, you have to set the modifier s
.
其次,您在此处使用断言:((?!foreach)|(?R))*
,但没有要匹配的实际字符.在 *
量词或其他东西之前至少需要一个点.
And secondly, you are using assertions here: ((?!foreach)|(?R))*
, but no actual characters to match. You need at least a dot before the *
quantifier or something.
#{foreach \$.*?}((?!foreach)|(?R)).*{/foreach}#s
为您的测试文本提供以下结果:>
#{foreach \$.*?}((?!foreach)|(?R)).*{/foreach}#s
gives the following result with your test text:
Array
(
[0] => {foreach $ABC}
in 1st loop
{foreach $XYZ}
in 2nd loop
{/foreach}
{/foreach}
[1] =>
)
这篇关于递归正则表达式不匹配模板块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!