假设我有以下字符串:
"<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>"
这是不正确的。
答案 0 :(得分:2)
在通用正则表达式中,没有办法以良好的方式处理嵌套。因此,当出现这样的问题时所有的胜利 - 永远不要使用正则表达式来解析XML / HTML。
在一些简单的情况下,它可能是有利的。如果像在你的例子中那样,嵌套级别有限,你可以简单地为每个级别添加一个正则表达式。
现在让我们分步进行。要处理第一个非嵌套属性,您可以使用
{[^}]*}
这匹配一个起始大括号,后跟任意数量的但一个右大括号,最后是一个右大括号。为简单起见,我会把它的核心放在一个非捕获组中,比如
{(?:[^}])*}
这是因为在插入备用的时候,需要它。
如果您现在允许除了右括号([^}]
)以外的任何其他嵌套级别的大括号,只需加入第一个正则表达式,像
{(?:{[^}]*}|[^}])*}
^^^^^^^ original regex inserted as alternative (to it self)
它允许一个级别的嵌套。再次这样做,加入这个正则表达式作为自己的替代,比如
{(?:{(?:{[^}]*}|[^}])*}|{[^}]*}|[^}])*}
^^^^^^^^^^^^^^^ previous level repeated
将允许另一级别的嵌套。如果需要,可以重复更多级别。
这不能处理属性名称和东西的捕获,因为你的问题不是很清楚你想要什么,但它向你展示了一种方式(最容易理解,或者......:P )处理正则表达式中的嵌套。
You can see it handle your example here at regex101
此致
答案 1 :(得分:0)
你正试图处理平衡的大括号。这需要递归正则表达式。根据定义,递归正则表达式不是常规的。无论如何,一些语言支持它们,例如Perl,PHP,ruby。 This是关于该主题的好教程。
通常,您应该使用完全成熟的解析器(如yacc)提取此类信息。
这是一个可以处理非平衡大括号的正则表达式:([ =]*)=(\{[^}]*\})
。这将匹配{<dd>sop</dd>}
和{st}
,这是正确的。不幸的是,它也会匹配{ <bb y={ <cc x={st}
,这不是你想要的。