正则表达式需要很长时间才能找到匹配项

时间:2017-06-29 09:44:07

标签: c# regex

这个正则表达式:

@"^(?:\s*)((?:[a-zA-Z]+[\s-]?)+[a-zA-Z]+)(?:\s*)$

花了这么长时间,在一些复杂的情况下,它太可怕了。

请问如何使用Web应用程序中的C#开发优化此正则表达式。

1 个答案:

答案 0 :(得分:3)

问题是,(?:[a-zA-Z]+[\s-]?)+导致正则表达式中的大量回溯,因为它位于其他模式之间,[\s-]?匹配1或 0 空格或-(即它是可选的),整个子模式减少到([a-zA-Z]+)+,从而导致catastrophic backtracking

使用

^(?!.{36})\s*([a-zA-Z]+(?:[\s-][a-zA-Z]+)*)\s*$

代替。请参阅the regex demo

<强>详情:

  • ^ - 字符串的开头
  • (?!.{36}) - 一个负面的预测,一旦匹配模式就会使匹配失败,即如果引擎从字符串的开头找到除换行之外的任何36个字符,则表示
  • \s* - 零个或多个空格
  • ([a-zA-Z]+(?:[\s-][a-zA-Z]+)*) - 第1组:
    • [a-zA-Z]+ - 一个或多个ASCII字母
    • (?:[\s-][a-zA-Z]+)* - 零个或多个序列:
      • [\s-] - 空格或-
      • [a-zA-Z]+ - 一个或多个ASCII字母
  • \s* - 0+尾随空格
  • $ - 字符串结尾(虽然可能会跟\n一起,但如果不需要则替换为\z