我需要构建一个正则表达式(.NET语法)来确定字符串是否以特定值结尾。具体地说,我需要测试文件是否具有特定的扩展名(或一组扩展名)。
我试图修复的代码使用的是:
.*\.(png|jpg|gif)$
在我的场景中,对于失败的匹配,这是非常慢的(可能是由于回溯。
只需在开始时删除.*
(这很好,因为API只测试匹配项,而不提取任何内容),就可以使正则表达式更高效。
它仍然感觉它的效率很低。我是不是漏掉了什么明显的东西?
不幸的是,我不能控制有问题的API,所以我需要一个正则表达式来做这件事,尽管我通常不认为正则表达式是适合这项工作的工具。
我还使用RegexOptions.RightToLeft
做了一些测试,发现使用^.*\.(png|jpg|gif)$
可以提高测试用例的性能,但是我找不到在正则表达式本身的字符串中指定RightToLeft
选项的方法,所以我不认为可以使用它。
发布于 2010-01-17 16:19:23
我没有访问C#的权限,所以我不能尝试...但是你应该能够避免太多的回溯,通过强制引擎首先找到字符串的结尾,然后匹配扩展名:
$(?<=\.(gif|png|jpg))
不过,我不确定后视对性能有什么影响。
发布于 2010-01-18 01:47:13
实际上,你也可以完全放弃正则表达式,使用String.EndsWidth
,如下所示:
var extensions = new String[] { ".png", ".jpg", ".gif" };
extensions.Any(ext => "something".EndsWith(ext));
我通常有这样的感觉,在这样的情况下,使用简单的字符串函数最终会更快,而不是试图找到一种聪明的方法来使用有效的正则表达式,在运行时和/或开发时间方面,除非您熟悉并知道什么是有效的正则表达式。
发布于 2010-01-17 16:12:34
使其专门查找句点,而不是扩展名之前的任何字符:
\.(png|jpg|gif)$
这将使它更安全(不会与x.xgif匹配),并且在找到句点之前,它根本不需要进行任何回溯(而不是对每个字符进行回溯)。
https://stackoverflow.com/questions/2081555
复制相似问题