提问人:RobertPitt 提问时间:9/20/2010 最后编辑:RobertPitt 更新时间:7/2/2011 访问量:4582
'正则表达式' VS '字符串比较运算符/函数'
'Regular Expression' VS 'String Comparison operators / functions'
问:
这个问题是围绕PHP的性能而设计的,但如果你愿意,你可以把它扩展到任何语言。
在使用 PHP 多年并不得不比较字符串之后,我了解到在性能方面,使用字符串比较运算符而不是正则表达式是有益的。
我完全理解某些操作必须使用正则表达式来完成,因为其复杂性很高,但对于可以通过正则表达式和字符串函数解析的操作。
举个例子:
PHP的
preg_match('/^[a-z]*$/','thisisallalpha');
C#
new Regex("^[a-z]*$").IsMatch('thisisallalpha');
可以很容易地完成
PHP的
ctype_alpha('thisisallalpha');
C#
VFPToolkit.Strings.IsAlpha('thisisallalpha');
还有很多其他的例子,但你应该明白我想表达的观点。
您应该尝试并倾向于哪个版本的字符串比较,为什么?
答:
它们都是语言的一部分是有原因的。IsAlpha 更具表现力。例如,当您正在查看的表达式本质上是 alpha 或不是 alpha 并且具有域含义时,请使用它。
但是,如果它是输入验证,并且可能会更改为包含下划线、破折号等,或者如果它使用其他需要正则表达式的逻辑,那么我会使用正则表达式。对我来说,这往往是大部分时间。
评论
看起来这个问题源于我们在这里的小争论,所以我觉得自己有义务做出回应。
PHP开发人员正在积极地对“性能”进行洗脑,其中出现了许多谣言和神话,包括诸如“双引号速度较慢”之类的愚蠢事情。正则表达式“慢”是这些神话之一,不幸的是,手册支持了这一点(参见preg_match页面上臭名昭著的评论)。事实是,在大多数情况下,你不在乎。除非你的代码被重复 10,000 次,否则你甚至不会注意到字符串函数和正则表达式之间的区别。如果你的代码重复了 10,000 次,那么在任何情况下你一定做错了什么,你将通过优化逻辑而不是通过剥离正则表达式来获得性能。
至于可读性,正则表达式确实很难阅读,但是,在大多数情况下,使用它们的代码更短、更干净、更简单(在上面的链接上比较你和我的答案)。
另一个重要的问题是灵活性,尤其是在 php 中,其字符串库不支持开箱即用的 unicode。在你的具体例子中,当你决定将你的网站迁移到utf8时会发生什么?你有点不走运,需要另一种模式,但会继续工作。ctype_alpha
preg_match
因此,正则表达式并不慢,可读性更强,更灵活。我们到底为什么要避免它们?
评论
当正则表达式可以替换多个原子字符串比较时,它们实际上会带来性能提升(并不是说这种微优化在任何方面都是明智的)。因此,通常大约有 5 次 strpos() 检查,建议改用正则表达式。此外,为了可读性。
这里还有另一个想法:PCRE 处理条件的速度比 Zend 内核处理 IF 字节码的速度更快。
但是,并非所有正则表达式的设计都是一样的。如果复杂度过高,正则表达式递归会扼杀其性能优势。因此,将正则表达式匹配和常规 PHP 字符串函数混合在一起通常是值得重新考虑的。适合工作和所有工作的工具。
PHP 本身建议在匹配简单时使用字符串函数而不是正则表达式函数。例如,在preg_match
手册页中:
如果您只想检查一个字符串是否包含在另一个字符串中,请不要使用 preg_match()。请改用 strpos() 或 strstr(),因为它们会更快。
或者从str_replace
手册页:
如果你不需要花哨地替换规则(如正则表达式),你应该始终使用这个函数而不是 ereg_replace() 或 preg_replace()。
但是,我发现人们试图使用字符串函数来解决正则表达式可以更好地解决的问题。例如,在尝试创建一个完整的单词字符串匹配器时,我遇到过有人为了“性能”而尝试使用(注意空格),而没有停下来思考空格为什么不是描述单词的唯一方法(想想需要多少字符串函数调用才能完全替换)。strpos($string, " $word ")
preg_match('/\bword\b/', $string)
我个人的立场是使用字符串函数来匹配静态字符串(即匹配始终相同的不同字符序列的匹配),并使用正则表达式来匹配其他所有内容。
同意 PHP 人员倾向于过分强调一个函数的性能而不是另一个函数的性能。这并不意味着性能差异不存在——它们确实存在——但大多数 PHP 代码(实际上大多数代码)的瓶颈比选择正则表达式而不是字符串比较要严重得多。要找出瓶颈在哪里,请使用 xdebug 的分析器。在担心微调单个代码行之前,先解决它出现的问题。
上一个:方法链接的影响
评论