嵌套 XML 属性的正则表达式

Regex for nested XML attributes

假设我有以下字符串:

"<aa v={<dd>sop</dd>} z={ <bb y={ <cc x={st}>ABC</cc> }></bb> }></aa>"

如何编写通用正则表达式(标签名称更改、属性名称更改)以匹配 {} 中的内容,<dd>sop</dd><bb y={ <cc x={st}>ABC</cc> }></bb>

我写的正则表达式 "(\s*\w*=\s*\{)\s*(<.*>)\s*(\})" 匹配

"<dd>sop</dd>} z={ <bb y={ <cc x={st}>ABC</cc> }></bb>" 这是不正确的。

您正在尝试处理平衡的括号组。这需要递归正则表达式。根据定义,递归正则表达式是不规则的。无论如何,有些语言支持它们,例如Perl,PHP,ruby。 This 是关于该主题的很好的教程。

通常,您应该使用成熟的解析器(如 yacc)提取此类信息。

这是一个可以处理 非平衡 大括号的正则表达式:([ =]*)=(\{[^}]*\})。这将匹配 {<dd>sop</dd>}{st},这是正确的。不幸的是,它也会匹配 { <bb y={ <cc x={st},这不是您想要的。

在通用正则表达式中,无法很好地处理嵌套。因此,当出现这样的问题时,所有的胜利 - 永远不要使用正则表达式来解析 XML/HTML.

在一些简单的情况下,它可能是有利的。如果像您的示例一样,嵌套的层数有限,您可以非常简单地为每一层添加一个正则表达式。

现在让我们分步进行。要处理第一个未嵌套的属性,您可以使用

{[^}]*}

这匹配一个起始大括号,后跟任意数量的任何东西 一个右大括号,最后是一个右大括号。为了简单起见,我将把它的核心放在一个非捕获组中,比如

{(?:[^}])*}

这是因为在插入备用的时候,需要它。

如果您现在允许除了右大括号 ([^}]) 之外的任何东西也是另一个嵌套的大括号 并简单地加入第一个正则表达式,例如

{(?:{[^}]*}|[^}])*}
    ^^^^^^^    original regex inserted as alternative (to it self)

它允许一层嵌套。再次做同样的事情,加入这个正则表达式作为自身的替代,比如

{(?:{(?:{[^}]*}|[^}])*}|{[^}]*}|[^}])*}
        ^^^^^^^^^^^^^^^    previous level repeated

将允许另一层嵌套。如果需要,可以对更多级别重复此操作。

虽然这不处理属性名称和其他内容的捕获,因为您的问题不太清楚您想要什么,但它向您展示了一种方式(i.m.o。最容易理解的, 或... :P) 来处理正则表达式中的嵌套。

You can see it handle your example here at regex101.

此致