Regex 正则表达式:非贪婪堆栈?

Regex 正则表达式:非贪婪堆栈?,regex,Regex,我必须在LaTeX和HTML文件中执行很多正则表达式。。我经常发现自己处于以下情况: 我希望像\mbox{\sqrt{2}}+\sqrt{4}这样的内容被剥离为\sqrt{2}+\sqrt{4}。 换句话说:“用其内容替换\mbox{…}的每一次出现 那么,我该怎么做呢 贪婪版本\mbox{(.*)}获取$1中的\sqrt{2}}+\sqrt{4 非贪婪版本\mbox{(.*?}以$1获取我\sqrt{2 两者都不是我想要的 我需要的是,正则表达式引擎以某种方式保持 位于(.*)前后位置的字符堆

我必须在LaTeX和HTML文件中执行很多正则表达式。。我经常发现自己处于以下情况:

我希望像
\mbox{\sqrt{2}}+\sqrt{4}
这样的内容被剥离为
\sqrt{2}+\sqrt{4}
。 换句话说:“用其内容替换\mbox{…}的每一次出现

那么,我该怎么做呢

贪婪版本
\mbox{(.*)}
获取$1中的
\sqrt{2}}+\sqrt{4
非贪婪版本
\mbox{(.*?}
以$1获取我
\sqrt{2

两者都不是我想要的

我需要的是,正则表达式引擎以某种方式保持 位于
(.*)
前后位置的字符堆栈,即
{
}
。因此,当在
*
中遇到新的
{
时,应将其放在堆栈上。当遇到
}
时,最后一个
{
应从堆栈中删除。当堆栈为空时,
*
完成

嵌套HTML标记也会出现类似的情况

因此,由于大多数正则表达式引擎为每个正则表达式创建一个FSA,堆栈应该是可行的,或者我遗漏了什么?一些我不知道的罕见的修改器?我想知道,为什么没有解决方案

当然,我可以用java/python/perl为自己编写一些代码……但我希望将其集成到正则表达式中:)

你好,吉尔伯特


(注:我省略了投影
+\sqrt{4}
以保持示例的小型化,
\
也应该转义)

这取决于您的正则表达式引擎,但可以使用.Net正则表达式引擎,如下所示

\\mbox{(
    (?>
        [^{}]+ 
        |   { (?<number>)
        |   } (?<-number>)
    )*
    (?(number)(?!))
)
}
\\mbox{(
(?>
[^{}]+ 
|   { (?)
|   } (?)
)*
(?(数字)(?!)
)
}
假设您使用的是IgnorePatternWhiteSpace


然后,您可以执行
regex.Replace(sourceText,“$1”)
以执行所需的转换


注意:它只适用于一个嵌套级别

您可以使用的另一个技巧是递归正则表达式(应该由PCRE和其他一些风格支持):

如果你心情正常,就不需要太多解释。
这里有一个类似的例子,但有点灵活(例如,更容易添加
[]
()
或其他平衡结构):


这在标准正则表达式中是不可能的;任意深度的嵌套不能用常规语言来表示。(以FSA中的F为例。)事实上。解决方案是使用一个解析器,该解析器可以处理比正则表达式更广泛的语法。@Oli除了没有现代正则表达式实现是真正规则的以外。(例如:
(.+)\1
不是常规的)我们需要知道您使用的是哪种正则表达式风格。它是与语言(Java、.NET、Perl等)相关联的风格之一,还是命令行工具(sed、grep等),还是编辑器中的查找/替换小部件(Emacs、vim、EditPad等)?@Brian发布了一个非常好的解决方案,但它只在.NET中工作。我非常喜欢这些正则表达式(我也知道),事实上这项任务通常无法完成。我对LaTeX了解不多,但它可能有字符串文字和注释(可能包含不平衡的大括号)。它可能也有转义符号。所有这些都可能会妨碍,或者使文档无法部分解析。如果您希望可靠地完成此操作,则必须使用解析器(我相信您可以找到)。我非常确定OP没有使用.NET正则表达式,但无论如何都要使用+1。)谢谢,至少看起来很有希望:)你知道吗,像VisualStudio或Expression Web这样的MS编辑器是否支持这种正则表达式?(我不确定他们是否都依赖.NET)我不这么认为,但是你应该能够使用来执行你的正则表达式替换。我只想再次指出我的评论。仅此而已。第三个选项是内联代码,但这通常是作弊。
s/
\\mbox{
  (
    (?:
      [^{}]+     #either match any number of non-braces
      |          #or
      \{[^{}]+}  #braces surrounding non-braces
    )*
  )
}
/$1/x;
\\mbox(\{([^{}]|(?1)+)*+\})
\\mbox\{([^{}]|\{(?1)*\})*\}