老实说,我想我应该先问一下这个问题的语法。
但如果你能理解我的意思,请用合适的标题编辑。
是否有一种方法可以使模式可以分割这样的文本。
{{START}}
{{START}}
{{START}}
{{START}}
{{END}}
{{END}}
{{END}}
{{END}}
所以每个{{START}}匹配它的{{END}}从内到外最后!
如果我不能只使用regex。那用PHP呢?
谢谢你。
这超出了正则表达式的能力,正则表达式只能解析正则语法。你所描述的需要一个下推自动机(正则语言由一个正则自动机定义)。
您可以使用正则表达式来解析单个元素,但是"深度"部分需要由具有内存概念的语言来处理(PHP可以很好地处理这个问题)。
因此,在您的解决方案中,正则表达式将仅用于识别您的标记,而跟踪深度和确定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);
解释:
part: ({{START'd+}}(?>[^{]++|(?1))*{{END'd+}})
模式的这一部分描述了{{START#}}
和{{END#}}
的嵌套结构
( # 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+}}))
这将匹配所有级别