【问题标题】:Regex matching doesn't finish正则表达式匹配未完成
【发布时间】:2013-12-10 09:29:42
【问题描述】:

我曾经 answered a question 讨论过将带引号的字符串与转义的引号匹配。

似乎有些情况在 .NET 上挂起并在 Mono(OutOfMemoryException)上崩溃,例如:

var reg = new Regex(@"^""([^\\""]*(\\"")*(\\[^""])*)*""");
reg.Match("\"                               ");

两个问题:

1) 为什么会这样?

2) 如何改进这个正则表达式?我希望它保留所有“功能”。

【问题讨论】:

  • 这可能是catastrophic backtracking的情况。您链接的问题有更好的答案。
  • 仅供参考,您的表达方式适用于我使用 Javascript 的正则表达式引擎:rexfiddle.net/slfowcR
  • 只是一个想法 - 为什么您实际上必须使用正则表达式来执行此操作?写一个简单的状态机来解析字符串不是更容易吗?您将绕过所有令人讨厌的回溯,这对于您提供的案例而言,成本会成倍增加。
  • @Luaan 的重点是正则表达式很难看,但如果你有很多正则表达式就很容易维护。创建多个状态机来处理许多情况会很烦人。当我输入的语法稳定并且我有时间时,也许值得这样做。
  • @TimS。我试图避免使用 ?: 因为我不太了解它并想创建自己的解决方案。显然,这不是一个好主意 :) 实际上,您对此链接的评论是一个很好的答案,谢谢。

标签: c# .net regex mono


【解决方案1】:

这确实是(cf Tim S.)与您的这部分模式的灾难性回溯:(\\[^""])*)* 它允许世界上所有可能的事情,并导致正则表达式引擎尝试太多可能性。 (如果您关注 Tim S. 链接,可以找到更好的插图)

执行此操作的另一种模式:

var reg = new Regex(@"(?s)""(?>[^\\""]+|\\{2}|\\.)*""");

(这个想法是匹配所有偶数个反斜杠(交替的第二部分),以确保允许真正的转义字符(交替的第三部分).)

【讨论】:

  • 我不认为我的正则表达式中有偶数个反斜杠,它只需要捕获未转义引号之间的所有内容。可以肯定的是,这有点过分。由于 Tim S. 仅提供了评论,我将接受您的回答,这也是正确的 :) 谢谢
  • @PiotrZierhoffer:请注意,您必须添加捕获括号来提取您想要的内容(或使用一对lookbehind/lookahead 将双引号括起来)。关于偶数个反斜杠,考虑这样的字符串:abc "def" "g\"hi" "jkl\\" "mn\\\"o"。结果必须是:defg"hijkl\`, mn\"o`。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多