【问题标题】:Regular expression takes unsual amount of time?正则表达式花费不寻常的时间?
【发布时间】:2013-12-16 00:35:54
【问题描述】:

这是我正在运行的代码:

Dim descriptionMatches As MatchCollection = Regex.Matches(pageJSON, "\[\[(([\w]+[\s]*)+)\]\], (([\w]+[\s]*)+)\\n")
Console.WriteLine(descriptionMatches.Count)

现在,一切正常,直到最后一行。看来 MatchCollection.Count() 方法执行起来确实需要很长时间,这么久,我已经运行程序超过 2 分钟了……

这里有一些附加信息。

  • 当我将正则表达式模式缩减为 "\[\[(([\w]+[\s]*)+)\]\]" 时,我得到了 35 个匹配项,而且这似乎是瞬间完成的。

  • 当我使用 for 循环解析 MatchCollection 时,如果我使用 for i=0 形式的循环来匹配collection.count,则不会执行循环(就像正则表达式仍在尝试分析输入字符串。如果我对每个都使用 a(不同之处在于最新的使用迭代器),我会在它冻结之前到达大约第 15 个匹配项。很奇怪不是吗?

  • 这是我要匹配的字符串的链接,如您所见,它不是有史以来最长的字符串:Wikipedia API result for SRS

  • 如果我的模式有问题,而您想建议我一个新模式,我要匹配的内容如下所示:

[[项目名称]],项目描述\n

我过去经常使用正则表达式,但我从来没有遇到过这种情况。如果有人知道是什么问题,请告诉我这是什么问题以及如何解决?

【问题讨论】:

  • 提示:[\w]\w[\s]\s。并尝试用(\w+\s+)*\w+ 替换(\w+\s*)+。并使用逐字字符串@"…\n",这样您就不必双重转义。

标签: .net regex vb.net performance


【解决方案1】:

您想匹配两个[[,后跟两个]]。让自己变得简单:

\[\[([^][]+)\]\], (.*?)\\n\*

在工作中查看http://regex101.com/r/kK5rO4

解释:

\[\[       find two literal [[ in a row
([^][]+)   match at least one character that is not ] or [ (note - the order matters)
           and "save" that match (so you can pull it out later)
\]\]       all the fun stops when you hit two closing brackets
           (but since the match already said "no closing brackets" there is no backtracking)
,          match comma followed by space
(.*?)      match the least amount you can until you get to…

\\n\*      literal \n* (both the \ and the * need a backslash to escape them

您需要一个 g 标志来让常规正则表达式匹配“所有实例”,但我认为您的其余代码已经有效地处理了这一点。

【讨论】:

  • 一开始很简单,然后(.*)+??什么?
  • 对不起 - 错字。已编辑,现在可以使用(请参阅链接中的演示)。
  • @minitech 你是对的。我的错。感谢您指出。
  • 我不确定是什么 ([^][]+)。 [^] 不应该表示字符串的开头吗?那 []+ 是什么意思?我以前从未见过这样使用方括号。
  • 这很棘手。一组方括号表示“此列表中的任何字符”。您可以有单个字符或组(例如 [a-z] 表示“从 a 到 z 包括在内的所有字符”。您可以使用插入符号 ^ 添加 NOT。“除数字之外的任何内容”可以是 [^0-9]。棘手的问题事情就是说“任何不是右括号的东西”而不关闭表达式。它必须是列表中的第一个字符 - 因此[^]] 表示“除了右括号之外的任何东西”。为了安全起见,我想要“任何东西都没有打开或右括号”,这让我找到了[^][]。有意义吗?
【解决方案2】:

您的正则表达式导致“catastrophic backtracking”,使其过于复杂。

考虑将您的正则表达式重写为更多 possessive

【讨论】:

    猜你喜欢
    • 2016-05-15
    • 1970-01-01
    • 2019-10-27
    • 2012-05-08
    • 2012-09-12
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多