"正则表达式"与"字符串比较运算符/函数"的区别。

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');

还有许多其他例子,但你应该明白我试图表达的观点。

在字符串比较中,你应该尝试并倾向于哪个版本?为什么?


你的示例都会失败,因为字符串中包含空格。 - Tim Pietzcker
这不是重点,只是想获得一些赞 :) - RobertPitt
2
我会纠正它们。通过正确的例子进行教育。 - gertas
5个回答

6

看起来这个问题是源于我们的一次小争论(此处),所以我感觉自己有点义务回应。

PHP开发者正在积极地被洗脑关于“性能”,从而出现许多谣言和神话,包括纯粹愚蠢的事情,比如“双引号更慢”。正则表达式被认为“慢”是其中之一,不幸的是手册也支持这种说法(请参见preg_match页面上臭名昭著的评论)。事实上,在大多数情况下,你并不在乎。除非你的代码重复了10000次,否则你甚至不会注意到字符串函数和正则表达式之间的区别。如果你的代码确实重复了10000次,那么你肯定做错了什么,通过优化你的逻辑,而不是剥离正则表达式,你将获得更好的性能。

至于可读性,正则表达式的确难以阅读,然而,使用它们的代码在大多数情况下更短、更清洁、更简单(比较上面链接中你和我的答案)。

另一个重要的问题是灵活性,尤其是在 PHP 中,其字符串库默认不支持 Unicode。举个具体的例子,如果您决定将网站迁移到 UTF-8,使用 ctype_alpha 就会遇到困难,而 preg_match 需要另一种模式,但仍然可以工作。
因此,正则表达式不比其他方法更慢、更难读,而且更加灵活。我们为什么要避免使用它们?

是的,这个问题确实源于那个小的“对话”,我认为在我着手处理之前,最好先听取其他程序员的意见。感谢您的观点+1,但正如我所说,我并不避免使用正则表达式,只是认为为了节省几个peta秒,我会倾向于使用字符串函数,因为随着我的应用程序的增长,每一点帮助都很重要。 - RobertPitt
11
“如果您的代码重复了 10,000 次,那么在任何情况下,您一定是在做某些错误的事情。” => 我不太同意这个说法。肯定有一些情况是合理的。 - Wrikken
...像“双引号比单引号慢”这样的愚蠢说法... - Máxima Alekz

1

正则表达式实际上可以带来性能提升(虽然这种微观优化并不明智),当它们可以替换多个原子字符串比较时。因此,通常在进行约五个strpos()检查时,建议使用正则表达式。更重要的是,这样做可以提高可读性。

还有一个思考的问题:PCRE可以比Zend内核处理IF字节码更快地处理条件语句。

然而,并非所有的正则表达式都是平等的。如果复杂度过高,正则表达式递归可能会破坏其性能优势。因此,经常重新考虑混合使用正则表达式匹配和常规PHP字符串函数。选择正确的工具来完成工作。


1

PHP本身建议在匹配明显的情况下使用字符串函数而不是正则表达式函数。例如,来自preg_match手册页面:

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

或者从str_replace手册页面:

如果您不需要复杂的替换规则(例如正则表达式),则应始终使用此功能,而不是使用ereg_replace()或preg_replace()。

然而,我发现人们试图使用字符串函数来解决本应使用正则表达式更好的问题。例如,在尝试创建完整单词字符串匹配器时,我发现有人尝试使用 strpos($string,“ $word”)(注意空格),为了“性能”,而没有停下来考虑空格并不是分隔单词的唯一方法(想想需要多少次字符串函数调用才能完全替换preg_match('/\bword\b/', $string)).

我的个人立场是将字符串函数用于匹配静态字符串(即匹配一组固定字符序列,其中匹配总是相同的),并将正则表达式用于其他所有内容。


0

它们都是语言的一部分,有各自的用途。IsAlpha更具表现力。例如,当你正在查看的表达式本质上是字母还是非字母,并且这对于领域意义很重要时,请使用它。

但如果它是输入验证,可能会更改以包括下划线、破折号等,或者如果它与其他需要正则表达式的逻辑一起使用,则我会使用正则表达式。这在我的大多数时间里都是如此。


谢谢您的回复,我知道这一点,这在我的原始帖子中已经提到了。我的想法是,对于两种方法都可以处理的操作,您会选择哪一种,并为什么选择它? - RobertPitt
编辑以更好地回答您的问题(我希望) - Mark Thomas

0

同意 PHP 开发者往往过分强调一个函数的性能优劣。这并不意味着性能差异不存在,它们确实存在,但大多数 PHP 代码(事实上大多数代码)比正则表达式与字符串比较的选择更糟糕。要找出瓶颈在哪里,请使用 xdebug 的分析器。在担心微调单个代码行之前,先解决它提出的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接