0

假设我有以下字符串:

"<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>"这是不正确的。

4

2 回答 2

2

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

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

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

{[^}]*}

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

{(?:[^}])*}

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

如果您现在允许除了右大括号( [^}]) 之外的任何其他内容也可以是另一个嵌套级别的大括号​​,并且只需加入第一个正则表达式,例如

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

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

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

将允许另一个级别的嵌套。如果需要,这可以重复更多级别。

这不处理属性名称和东西的捕获,因为你的问题不是很清楚你想要什么,但它向你展示了一种处理方式(imo最容易理解,或者......:P)嵌套在正则表达式中。

您可以在 regex101 看到它处理您的示例

问候

于 2016-05-09T11:06:37.063 回答
0

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

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

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

于 2016-05-09T11:03:13.383 回答