Php 如何使用正则表达式创建循环?

Php 如何使用正则表达式创建循环?,php,regex,Php,Regex,老实说,我想我应该先向你们请教这个问题的语法 但是如果你能理解我的意思,请用合适的标题编辑标题 有没有一种方法可以使图案像这样分割文本 {{START}} {{START}} {{START}} {{START}} {{END}} {{END}} {{END}} {{END}} 所以每个{{START}}从内部第一个到外部最后一个匹配它的{{END} 如果我不能只用正则表达式。使用PHP做这件事怎么

老实说,我想我应该先向你们请教这个问题的语法

但是如果你能理解我的意思,请用合适的标题编辑标题

有没有一种方法可以使图案像这样分割文本

{{START}}
    {{START}}
        {{START}}
            {{START}}
            {{END}}
        {{END}}
    {{END}}
{{END}}
所以每个{{START}}从内部第一个到外部最后一个匹配它的{{END}

如果我不能只用正则表达式。使用PHP做这件事怎么样


首先谢谢你。

这超出了正则表达式的能力,它只能解析正则语法。您所描述的内容需要一个下推自动机(正则语言是由a定义的)

您可以使用正则表达式来解析各个元素,但是“深度”部分需要由一种具有内存概念的语言来处理(PHP适合这样做)


因此,在您的解决方案中,正则表达式仅用于识别您的标记,而跟踪深度和确定结束标记属于哪个元素的真正逻辑必须是您的程序本身。

纯正则表达式无法实现这一点,但通过简单的循环即可实现

JS示例:

//[.\s\S]* ensures line breaks are matched (dotall not supported in JS)
var exp = /\{\{START\}\}([.\s\S]*)\{\{END\}\}/;

var myString = "{{START}}\ntest\n{{START}}\ntest 2\n{{START}}\ntest 3\n{{START}}\ntest4\n{{END}}\n{{END}}\n{{END}}\n{{END}}";

var matches = [];
var m = exp.exec(myString);
while ( m != null ) {
    matches.push(m[0]);
    m = exp.exec(m[1]);
}

alert(matches.join("\n\n"));
PHP(我不知道这是否正确,自从我使用PHP以来,它已经存在了很久)

输出:

{{START}}
test
{{START}}
test 2
{{START}}
test 3
{{START}}
test4
{{END}}
{{END}}
{{END}}
{{END}}

{{START}}
test 2
{{START}}
test 3
{{START}}
test4
{{END}}
{{END}}
{{END}}

{{START}}
test 3
{{START}}
test4
{{END}}
{{END}}

{{START}}
test4
{{END}} 

这是可能的!您可以使用递归正则表达式获得各级内容:

$data = <<<LOD
{{START1}}
    aaaaa
    {{START2}}
        bbbbb
        {{START3}}
            ccccc
            {{START4}}
                ddddd
            {{END4}}
        {{END3}}
    {{END2}}
{{END1}}
LOD;

$pattern = '~(?=({{START\d+}}(?>[^{]++|(?1))*{{END\d+}}))~';
preg_match_all ($pattern, $data, $matches);

print_r($matches);
现在的问题是,您不能仅使用这一部分捕获所有级别,因为字符串的所有字符都被模式使用。换句话说,您无法匹配字符串的重叠部分

问题是将所有这部分都封装在一个零宽度断言中,该断言不使用像lookahead
(?=…)
这样的字符,结果:

(?=({{START\d+}}(?>[^{]++|(?1))*{{END\d+}}))

这将匹配所有级别。

大多数风格的正则表达式都无法做到这一点,尽管在我的知识之外,还有一些技巧使它在Perl等语言中成为可能。阅读关于泵引理的文章,找出你为什么不能这样做。我想你的格式化是某种输入。如果你再多解释一点,也许可以建议一些替代方法。听起来你好像在试图解析某些东西。。。潜在重复项:;提问前请使用搜索功能。现在有这么多的重复链接,请分享你迄今为止的尝试,提供参考,并让我们知道为什么它不适合你..OP需要一个PHP解决方案。再试一次。添加了PHP,不知道它是否正确。多年没有使用过PHP。PHP使用一个正则表达式引擎,它不仅可以使用正则表达式。-所以你的答案只是学术性的,而不是实际问题。但是,您也可以使用该引擎来描述它的轮廓。仅第一部分不适用于PHP/PCRE。
(             # open the first capturing group
{{START\d+}}  
(?>           # open an atomic group (= backtracks forbidden)
    [^{]++    # all that is not a { one or more times (possessive)
  |           # OR
    (?1)      # refer to the first capturing group itself
)             # close the atomic group
{END\d+}}     # 
)             # close the first capturing group
(?=({{START\d+}}(?>[^{]++|(?1))*{{END\d+}}))