You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

正则表达式移除非嵌套<mrow>标签首尾括号的问题排查

从非嵌套<mrow>标签提取内容并移除首尾括号的正则方案

问题背景

需要从类似<mrow>(<mn>1000001</mn>)</mrow>的字符串中提取内部的<mn>1000001</mn>,要求仅处理非嵌套的<mrow>...</mrow>标签,同时移除标签首尾可能存在的括号。

最初使用的正则模式:

<mrow[^\>]*>\(?((?:(?!<mrow>[^\>]*>|<\/mrow>).)*)\)?<\/mrow>

预期替换结果为<mn>1000001</mn>,但实际得到<mn>1000001</mn>),残留了右括号,处理复杂数学公式时该问题仍存在。

问题原因

原正则的核心问题在于贪婪匹配导致右括号被捕获组包含:

  • 中间的捕获组(?:(?!<mrow>[^\>]*>|<\/mrow>).)*是贪婪模式,会尽可能匹配所有不触发负向预查的字符,包括末尾的右括号)
  • 后面的\)?因为捕获组已经吃掉了右括号,没有可匹配的字符,所以无法移除这个括号

正确正则实现

调整正则结构,将可选括号移到捕获组前后,并使用非贪婪模式确保捕获组不会包含末尾的括号,同时增加空白处理提升鲁棒性:

<mrow[^>]*>\s*\(?\s*((?:(?!<mrow[^>]*>|</mrow>).)*?)\s*\)?\s*</mrow>

正则解析

  • <mrow[^>]*>:匹配任意属性的<mrow>起始标签
  • \s*\(?\s*:匹配可能的前置空白+可选左括号
  • ((?:(?!<mrow[^>]*>|</mrow>).)*?):非贪婪捕获内部内容,负向预查确保不匹配嵌套的<mrow>标签
  • \s*\)?\s*:匹配可能的后置空白+可选右括号
  • </mrow>:匹配结束标签

使用示例

以原字符串为例,替换时引用捕获组$1(不同语言可能用\1或其他语法),即可得到干净的<mn>1000001</mn>。

对于更复杂的公式如<mrow> ( <mn>123</mn> + <mn>456</mn> ) </mrow>,同样能正确提取<mn>123</mn> + <mn>456</mn>。

内容的提问来源于stack exchange,提问作者Xavier Junqué

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 14:23:01