递归正则表达式:如何设置不匹配的字符串,而不是单个字符


Recursive regular expression: how to set a mismatch with the string, rather than individual characters

我的php代码:

      $exp = 'zzz<pre>sssss<pre>fff</pre>ff</pre>zzz';     
      'preg_match_all("#<pre>((?>[^(?:<pre>)(?:</pre>)]|(?R))*)</pre>#si", $exp, $matches);
        $i = 0;
        foreach ($matches as $item) {           
            foreach ($item as $elem)
            {
                echo "$i  ", 'htmlentities($elem), "<br>";
            }
            $i++;
        }
输出:

0 <pre>sssss<pre>fff</pre>ff</pre>

1 sssss<pre>fff</pre>ff

这很好- regex工作并找到嵌套标签<pre>。但是我有一个问题:

[^(?:<pre>)(?:</pre>)]

我可以用字符< / p r e >设置dis马赫,但是我需要用字符串<pre></pre>设置dis马赫。因此,如果我在原始文本中至少添加符号pr, regex将无法正常工作。

示例: $exp = zzz<pre>ssspss<pre>fff</pre>ff</pre>zzz; // p inside ssspss

输出

0 <pre>fff</pre>

1 fff

告诉我,如何构建正则表达式来设置与字符串的不匹配,而不是单个字符?

您可能想使用反向向前看而不是反向字符类:

~<pre>((?>(?!</?pre).|(?R))*)</pre>~si

见regex101.com测试

你的正则表达式没有按预期工作,因为[^(?:<pre>)(?:</pre>)]匹配任何不在[^否定字符类中的字符。

</pre)(?:>

旁注: Regex不适合解析任意嵌套的html。