嵌套时获取外部“配对”

时间:2013-05-16 19:57:45

标签: python regex

我正在使用正则表达式<@(.+?)@>来匹配以下模式:

<@set:template default.spt @>

它工作正常,但我遇到了需要嵌套模式的情况,例如:

<@set:template <@get:oldtemplate @> @>

我没有获得父对(&lt; @和@&gt;),而是获得以下内容:

<@set:template <@get:oldtemplate @>

我不希望它让孩子一个,我只想在所有嵌套情况下最外面的父。如何修复我的正则表达式,以便它能为我做到这一点?我想如果我知道如何要求每个<@父母内部有一个@>,我就能做到这一点,但我不知道如何强制执行。{/ p>

2 个答案:

答案 0 :(得分:5)

您所描述的是“非常规语言”。它无法使用正则表达式进行解析。

好的,如果您愿意对嵌套级别设置限制,从技术上讲,可以使用regexp进行操作。但它会很难看。

如果您可以在标签中添加@s的条件,以下是如何使用一些(增加的)最大嵌套深度来解析您的东西:

no nesting: <@[^@]+@>
up to 1:    <@[^@]+(<@[^@]+@>)?[^@]*@>
up to 2:    <@[^@]+(<@[^@]+(<@[^@]+@>)?[^@]*@>)?[^@]*@>
up to 3:    <@[^@]+(<@[^@]+(<@[^@]+(<@[^@]+@>)?[^@]*@>)?[^@]*@>)?[^@]*@>
...

如果你不能在你的标签中禁止单独使用@,那么你必须用[^@]替换(?:[^<@]|<[^@]|@[^>])的每个实例。

考虑一下,然后考虑扩展你的正则表达式来解析最多10个深度嵌套。

在这里,我会为你做的:

<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[
^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<
[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@
[^>])+(<@(?:[^<@]|<[^@]|@[^>])+@>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>]
)*@>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@
>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@>)?
(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@>

我希望我的答案显示 regexp不是解析语言的正确工具。 传统词法分析器(tokenizer)和解析器组合会做得更好工作,明显更快,并将处理无限期的嵌套。

答案 1 :(得分:1)

我认为您不能使用正则表达式执行此操作,请参阅this question的答案,该答案会提出类似的问题。正则表达式不足以处理任意级别的嵌套,如果你只有2级嵌套,那么它应该是可能的,但也许正则表达式不适合这项工作。