C# 正则表达式匹配需要很长时间才能执行

C# 正则表达式匹配需要很长时间才能执行,c#,regex,performance,C#,Regex,Performance,我编写了一个正则表达式,将文件路径解析为不同的组(驱动器、目录、文件、扩展名) =>好的 但当我尝试使用我知道不匹配的路径进行测试时,如下所示: string path = @"C:\Documents and Settings\jhr\My Documents\Visual Studio 2010\Projects\FileEncryptor\Dds.FileEncryptor\Dds.FileEncryptor?!??????"; =>错误 当我调用这部分代码时,测试冻结 Match ma

我编写了一个正则表达式,将文件路径解析为不同的组(驱动器、目录、文件、扩展名)

=>好的

但当我尝试使用我知道不匹配的路径进行测试时,如下所示:

string path = @"C:\Documents and Settings\jhr\My Documents\Visual Studio 2010\Projects\FileEncryptor\Dds.FileEncryptor\Dds.FileEncryptor?!??????";
=>错误

当我调用这部分代码时,测试冻结

Match match = s_fileRegex.Match(path);
当我查看Process Explorer时,我看到进程QTAgent32.exe挂在处理器的100%位置。这是什么意思?

为什么不使用函数呢

  • 驱动器:

  • 目录:减去为驱动器获取的内容

  • 文件名:

  • 分机:


我只需要使用
FileInfo
Path
类来获取信息

如果您选择使用正则表达式,
然后请注意,正则表达式并不匹配所有合法文件名:正则表达式中缺少一大堆合法文件名标记。

您遇到的问题是调用正则表达式,这是由于正则表达式可以通过大量方式匹配字符串的开头,由于.NET中的回溯正则表达式引擎,因此性能较慢

我认为您在正则表达式中使用
*
太频繁了<代码>*并不表示“连接”-它表示“0次或更多次”。例如,此处不应有
*

((?<DRIVE>[a-zA-Z]):\\)*
((?[a-zA-Z]):\)*

最多应有一种驱动器规格。您应该在此处使用
,否则,如果您希望强制执行驱动器规格,则根本不需要量词。类似地,正则表达式中似乎还有其他地方的量词不正确。

Mark Byers是正确的,因为问题的原因是,但导致问题的是最后一部分,而不是与驱动器号匹配的位

例如,在

(?<FILE>
  ([a-zA-Z0-9_]+
    (
      ([a-zA-Z0-9_\s_\-\.]*[a-zA-Z0-9_]+)
    |
      ([a-zA-Z0-9_]+)
    )\.
    (?<EXTENSION>[a-zA-Z0-9]{1,6})
  $)
)
可以通过多种不同的方式匹配相同的字符串,这些方式将随着文件名的长度呈指数增长

当正则表达式的扩展部分无法匹配时,正则表达式引擎会回溯并尝试对文件名部分进行不同的排列,希望这能使扩展部分匹配-当然它永远不会匹配,但正则表达式引擎无法解决这一问题,当要求在您提供的路径上测试正则表达式时,将在1.000.000次迭代后中止匹配尝试。C#regex引擎将缓慢运行,直到耗尽所有排列,在此期间将CPU锁定在100%

为了解决这个问题,通常需要避免重复元素的重复,避免匹配相同内容的替换,并可能将匹配的部分包含在其中,如果正则表达式的后续部分失败,这些部分将不会被回溯


但是,在您的情况下,最好使用正确的工具来完成作业,这些是.NET的路径操作功能。

在验证之前您考虑过吗?为什么不使用path类中的有用方法?没有必要使用正则表达式来提取这些信息。在这里使用正则表达式确实是错误的。我仍然想知道为什么这个正则表达式会杀死regexr.com:>回答得好,tyvm:)(+1)也许你可以把这个链接放在你的答案中,它很好地解释了这是如何发生的:谢谢你非常清楚的回答。你是对的,我将使用.NET framework上可用的函数!
((?<DRIVE>[a-zA-Z]):\\)*
(?<FILE>
  ([a-zA-Z0-9_]+
    (
      ([a-zA-Z0-9_\s_\-\.]*[a-zA-Z0-9_]+)
    |
      ([a-zA-Z0-9_]+)
    )\.
    (?<EXTENSION>[a-zA-Z0-9]{1,6})
  $)
)
([a-zA-Z0-9_\s_\-\.]*[a-zA-Z0-9_]+)
|
([a-zA-Z0-9_]+)