【发布时间】:2010-01-17 15:58:56
【问题描述】:
我需要构建一个正则表达式(.NET 语法)来确定字符串是否以特定值结尾。具体来说,我需要测试一个文件是否具有特定的扩展名(或一组扩展名)。
我正在尝试修复的代码正在使用:
.*\.(png|jpg|gif)$
在我的场景中,这对于失败的匹配来说非常慢(可能是由于回溯。
在开始时简单地删除.*(这很好,因为API 只测试匹配并且不提取任何内容)使正则表达式更加高效。
还是觉得效率很低。我在这里遗漏了什么明显的东西吗?
不幸的是,我无法控制相关 API,因此我需要一个正则表达式来执行此操作,尽管我通常不会认为正则表达式是适合这项工作的工具。
我还使用RegexOptions.RightToLeft 进行了一些测试,发现使用^.*\.(png|jpg|gif)$ 可以从我的测试用例中挤出更多性能,但是我找不到在正则表达式本身的字符串,所以我认为我不能使用它。
【问题讨论】:
-
\.(png|jpg|gif)$的缓慢程度有多大,因为我认为这是使用正则表达式最简单的方法。其余的取决于实施。 -
为什么不直接遍历有效扩展的数组并使用
.EndsWith?简单的字符串比较比正则表达式引擎快得多。 -
需要多快?在 Ruby(最慢的语言之一)中,我每秒可以比较 348,000 条路径。我会选择更简单的正则表达式,不是因为它更快,而是因为它更容易阅读和理解。
-
@Wayne:只有当你永远被一些扩展锁定时,它才会更容易阅读和理解。如果以后你想支持
bmp怎么办?tif?tiff?apng?或者纠正jpeg实际上也是一个广泛使用的JPEG扩展?你的正则表达式很快就会变成一个很难diff的单行怪物,我的数组仍然可以维护和理解。 -
@Kenny,说得好。在 Ruby 中,可以很容易地用字符串构建正则表达式。这肯定会影响我对什么是容易的和什么是困难的看法。从扩展数组开始,可以像这样简单地得到一个正则表达式:Regexp.new('.' + extensions.join('|') + '$')。如果可以用 C# 中的字符串制作正则表达式,则可以使用相同的技术(不同的语法)。