字符串操作与Regexps
我们经常被告知Regexps很慢,应尽可能避免。
但是,考虑到自己做一些字符串操作的开销(不是在谈论算法错误 - 这是一个不同的问题),特别是在PHP
或Perl
(也许是Java
)中有什么限制,在这种情况下,我们可以考虑字符串操作做一个更好的选择? 什么regexps特别是CPU贪婪?
例如,对于以下内容,在C++
, Java
, PHP
或Perl
,您会推荐什么
正则表达式可能会更快:
s/abc/def/g
或a ... while((i=index("abc",$x)>=0) ...$y .= substr()...
基础解决方案? s/(d)+/N/g
或扫描算法 但是关于
s/((0|w)+?[xy]*[^xy]){2,7}/u/g
手工制作的特定算法会不会更快(写时间更长)?
编辑
问题的关键是要确定什么样的正则表达式更好地通过字符串操作专门针对给定的问题重写?
EDIT2
一个常见的实现是Perl正则表达式。 例如在Perl中 - 需要知道它们是如何实现的 - 要避免使用哪种正则表达式,因为实现会使该过程变得漫长而无效? 它可能不是一个复杂的正则表达式...
编辑2011年7月 (根据评论)
我并不是说所有的正则表达式都很慢。 一些特定的正则表达式模式由于其特定的处理和由于其实现而被认为是缓慢的。
例如,在最近的Perl / PHP实现中,已知的速度很慢 - 应该避免?
答案预计来自已经有自己的研究人员(分析人员......),并且能够提供关于推荐/要避免的内容的一般性指导方针。
使用正则表达式处理文本的一个很好的特性是模式是高层次的和声明式的。 这留下了实现相当大的优化空间,例如分解最长的公共前缀或使用Boyer-Moore作为静态字符串。 简洁的符号使专家更快地阅读。 我立即明白了什么
if (s/^(.)//) {
...
}
正在做, index($_, 0, 1) = ""
看起来比较嘈杂。
正则表达式的重要考虑因素不是下限,而是上限。 这是一个强大的工具,所以人们相信它能够正确地从XML,电子邮件地址或C ++程序中提取令牌,并且没有意识到需要更强大的工具,比如解析器。
谁说正则表达式很慢? 至少在Perl中,它们往往是操作字符串的首选方法。
正则表达式在电子邮件验证等方面不好,因为主题太复杂,不是因为它们很慢。 一个合适的电子邮件验证正则表达式的长度超过6000个字符,它甚至不处理所有的情况(你必须先删除注释)。
至少在Perl 5中,如果它有一个语法,它可能不应该被一个正则表达式解析。
如果正则表达式已经发展到不再容易维护(请参阅前面的电子邮件验证示例)或分析表明正则表达式是代码的慢组件,您还应该将正则表达式重写为自定义函数。
您似乎关心正则表达式与自定义算法的速度,但在您证明它与分析器配合使用之前,这不是一个有效的关注点。 以最易维护的方式编写代码。 如果正则表达式清晰,则使用正则表达式。 如果自定义算法清晰,则使用自定义算法。 如果您发现在分析代码后耗费大量时间,那么就开始寻找替代方案。
正则表达式永远不会比用于特定目的的手工算法更快。 更糟的是,在PHP中,它们必须在第一次使用时进行编译(之后使用高速缓存)。
但是,它们肯定更简洁。 此外,编写自定义算法通常比正则表达式慢,因为正则表达式引擎通常以更低级的语言实现,调用函数的开销更少等。
例如, preg_replace('/a/', 'b', $string)
几乎肯定会比通过字符串在PHP中循环更快。 但这在执行时间中是一个不变的惩罚,有时由于回溯,正则表达式可能会有更差的渐近行为。
强烈建议您了解正则表达式是如何实现的,以便您可以知道何时编写低效的表达式。
链接地址: http://www.djcxy.com/p/16549.html上一篇: String manipulation vs Regexps
下一篇: What would be a globally accepted regular expression to match e