6

这个问题是围绕 PHP 中的性能设计的,但如果您愿意,您可以将其扩展到任何语言。

经过多年使用 PHP 并不得不比较字符串后,我了解到在性能方面使用字符串比较运算符而不是正则表达式是有益的。

我完全理解某些操作必须使用正则表达式来完成,直到复杂性,但对于可以通过正则表达式和字符串函数解决的操作。

举个例子:

PHP

preg_match('/^[a-z]*$/','thisisallalpha');

C#

new Regex("^[a-z]*$").IsMatch('thisisallalpha');

可以很容易地完成

PHP

ctype_alpha('thisisallalpha');

C#

VFPToolkit.Strings.IsAlpha('thisisallalpha');

还有很多其他的例子,但你应该明白我想要表达的意思。

您应该尝试使用哪个版本的字符串比较,为什么?

4

5 回答 5

6

看起来这个问题是由我们在这里的小争论引起的,所以我觉得自己有义务做出回应。

php 开发人员正在积极地对“性能”进行洗脑,因此出现了许多谣言和神话,包括诸如“双引号更慢”之类的愚蠢的事情。正则表达式“慢”是这些神话之一,不幸的是手册支持(参见 preg_match 页面上的臭名昭著的评论)。事实是,在大多数情况下,你不在乎。除非您的代码重复 10,000 次,否则您甚至不会注意到字符串函数和正则表达式之间的区别。而且,如果您的代码确实重复了 10,000 次,那么无论如何您一定是做错了什么,并且您将通过优化逻辑而不是通过剥离正则表达式来获得性能。

至于可读性,正则表达式确实很难阅读,但是,在大多数情况下,使用它们的代码更短、更干净、更简单(比较你和我在上面链接上的答案)。

另一个重要的问题是灵活性,尤其是在 php 中,它的字符串库不支持开箱即用的 unicode。在您的具体示例中,当您决定将站点迁移到 utf8 时会发生什么?ctype_alpha你有点不走运,需要preg_match另一种模式,但会继续工作。

所以,正则表达式并不慢、更易读、更灵活。我们到底为什么要避开它们?

于 2010-09-20T09:43:06.067 回答
1

当匹配很简单时,PHP 本身建议使用字符串函数而不是正则表达式函数。例如,从preg_match手册页:

如果您只想检查一个字符串是否包含在另一个字符串中,请不要使用 preg_match()。请改用 strpos() 或 strstr() ,因为它们会更快。

或从str_replace手册页:

如果您不需要花哨的替换规则(如正则表达式),则应始终使用此函数而不是 ereg_replace() 或 preg_replace()。

但是,我发现人们尝试使用字符串函数来解决可以通过正则表达式更好地解决的问题。例如,当尝试创建一个全字字符串匹配器时,我遇到过有人试图使用strpos($string, " $word ")(注意空格),为了“性能”,没有停下来思考空格不是描绘的唯一方法一个词(想想完全替换需要多少个字符串函数调用preg_match('/\bword\b/', $string))。

我个人的立场是使用字符串函数来匹配静态字符串(即匹配始终相同的不同字符序列的匹配)和其他所有内容的正则表达式。

于 2010-09-20T13:06:08.200 回答
1

当正则表达式可以替换多个原子字符串比较时,它们实际上会带来性能提升(并不是说这种微优化在任何方面都是明智的)。所以通常大约五个 strpos() 检查它是明智的,而不是使用正则表达式。Moreso为了可读性。

这里还有一个总结的想法:PCRE 处理条件的速度比 Zend 内核处理 IF 字节码的速度要快。

但是,并非所有的正则表达式都被设计成相同的。如果复杂度太高,正则表达式递归可能会扼杀其性能优势。因此,经常需要重新考虑混合正则表达式匹配和常规 PHP 字符串函数。适合工作的正确工具。

于 2010-09-20T10:12:56.017 回答
0

出于某种原因,它们都是语言的一部分。IsAlpha 更具表现力。例如,当您正在查看的表达式本质上是否为 alpha 并且具有域含义时,请使用它。

但是,如果它是一个输入验证,并且可能被更改为包括下划线、破折号等,或者如果它是需要正则表达式的其他逻辑,那么我会使用正则表达式。这往往是我的大部分时间。

于 2010-09-20T09:23:36.423 回答
0

同意 PHP 人倾向于过分强调一个功能的性能而不是另一个功能。这并不意味着性能差异不存在——它们确实存在——但大多数 PHP 代码(实际上是大多数代码)的瓶颈比选择正则表达式而不是字符串比较要严重得多。要找出瓶颈在哪里,请使用 xdebug 的分析器。在担心微调单个代码行之前解决它出现的问题。

于 2010-09-20T13:10:33.043 回答