我应该避免正则表达式吗?

时间:2009-06-15 23:42:48

标签: regex

我认识的人一直在告诉我应该避免RegEx,因为它是重量级的或者涉及繁重的处理。这是真的?这让我耳边鼓掌,直到现在我的耳膜响了起来。

我不知道为什么他告诉我。它可能来自经验还是仅仅是三手资料(你知道我的意思......)?

所以,明白地说,我为什么要避免使用正则表达式?

我希望SO社区的主人提供信息,与我分享他们的想法。谢谢你们!

22 个答案:

答案 0 :(得分:26)

不要避免它们。它们是一个很好的工具,当使用得当可以为您节省大量的时间和精力。此外,谨慎使用的良好实现不应特别占用CPU资源。

答案 1 :(得分:21)

如果您可以使用常见的字符串操作轻松执行相同的操作,则应避免使用正则表达式。

在大多数情况下,正则表达式用于相同操作需要大量常见字符串操作的情况,因此避免使用正则表达式当然没有意义。

答案 2 :(得分:18)

言过其实?不,他们非常强大和灵活。

过度使用?绝对。特别是在解析HTML时(经常出现在这里)。

这是另一个“适合工作的正确工具”方案。有些人走得太远,并尝试将它用于一切。

你是对的,因为你可以用子串和/或拆分做很多事情。你会经常达到一个目的,那些你正在做的事情会变得如此复杂,以至于你必须改变方法,或者你最终编写了太多脆弱的代码。正则表达式(相对)易于扩展。

但手写代码几乎总是更快。一个很好的例子是Putting char into a java string for each N characters。正则表达式解决方案更简洁,但有一些问题,手写循环没有,并且太多慢。

答案 3 :(得分:12)

您可以使用几乎任何技术替换您的问题中的“正则表达式”,并且您会发现那些对该技术了解不足或者懒得学习制作此类声明的技术的人。

正则表达式没有什么重要的。程序员使用正则表达式让自己陷入麻烦的最常见方式是他们尝试使用单个正则表达式做太多。如果您使用正则表达式来实现它们的目的(简单模式匹配),那么您将很难编写比等效正则表达式更高效的过程代码。鉴于对正则表达式的熟练程度,正则表达式编写时间更短,更易于阅读,并且可以粘贴到RegexBuddy等工具中进行可视化。

答案 4 :(得分:8)

作为基本的解析器或验证器,使用正则表达式,除非您编写的解析或验证代码更容易阅读。

对于复杂的解析器(即递归下降解析器),仅使用正则表达式来验证词法元素,而不是查找它们。

最重要的是,最好的正则表达式引擎可以很好地进行验证工作,在某些情况下可能比您自己编写的代码更有效,而在其他情况下,您的代码会表现得更好。根据您的需要使用手写状态机或正则表达式编写代码,但如果性能测试显示正则表达式效率非常低,则可以从正则表达式更改为手写代码。

答案 5 :(得分:7)

“当你拿锤子时,一切看起来像钉子。”

正则表达式是一个非常有用的工具;但我同意他们使用的每一个地方都没有必要。对他们来说,一个积极的因素是,因为它们往往很复杂并且在它们所处的地方使用得非常多,所以应用正则表达式的算法往往会得到很好的优化。也就是说,学习正则表达式所涉及的开销可能很高。非常高。

正则表达式是否适用于所有适用情况的最佳工具?可能不是,但另一方面,如果你一直使用字符串验证和搜索,你可能会使用正则表达式;一旦你这样做,你已经掌握了使用该工具所需的知识,可能比任何其他工具更有效,更快捷。但是,如果您没有这种经验,那么学习它实际上会拖累您的实施效率。所以我认为这取决于你愿意投入学习新范式的时间,以及你项目中涉及的匆忙程度。总的来说,我认为正则表达式非常值得学习,但与此同时,坦白说,学习过程可能很糟糕。

答案 6 :(得分:5)

我认为,如果你学习的语言本能地说正则表达式,你会倾向于他们,因为他们只是解决了很多问题。 IE,你可能永远不会学习使用split,因为regexec()可以解决更广泛的问题,一旦你习惯了它,为什么要在其他地方看?

另一方面,我敢打赌C和C ++程序员首先会考虑其他选项,因为它没有内置到语言中。

答案 7 :(得分:5)

你知道,鉴于我是很多人所说的“年轻”,我听到过太多关于RegEx的批评。你知道,“他有一个问题,并试图使用正则表达式,现在他有两个问题”。

说真的,我没理解。它是一个像其他任何工具一样的工具如果您需要一个包含一些文本的简单网站,则不需要PHP / ASP.NET / STG44。仍然没有讨论是否应该避免任何这些问题。多奇怪。

根据我的经验,RegEx可能是我作为开发人员遇到过的最有用的工具。对于#1安全问题,它是最有用的工具:解析用户输入。如果不是几天的编码和创建潜在的错误(阅读:糟糕的)代码,我已经节省了我几个小时。

使用现代CPU,我看不到这里的性能问题。我非常愿意为了一些质量和安全而牺牲一些周期。 (但情况并非总是如此,但我认为这些情况很少见。)

仍然,RegEx非常强大。拥有权利的同时也被赋予了重大的责任。这并不意味着你可以随时使用它。只有它的力量值得使用。

如上所述,使用RegEx进行HTML解析就像是装满枪的俄罗斯轮盘。不要过分,包括RegEx。

答案 8 :(得分:4)

言过其实?否

利用不足?是

答案 9 :(得分:4)

您还应该不惜一切代价避免使用浮点数。那是你在嵌入式环境中编程的时候。

说真的:如果你正常进行软件开发,你应该使用正则表达式,如果你需要做一些用简单的字符串操作无法实现的东西。我会说任何普通的程序员都无法以比对应的正则表达式更快的方式实现使用正则表达式做得最好的东西。编译完成后,正则表达式将作为状态机器工作,并将其优化到接近完美状态。

答案 10 :(得分:3)

如果有更多人知道如何使用合适的解析器生成器,那么使用正则表达式的人就会减少。

答案 11 :(得分:3)

不要避免它,但要问问自己它们是否是你必须解决的任务的最佳工具。也许有时正则表达式很难使用或调试,但它们在某些情况下确实很有用。问题是为每项任务使用适当的工具,通常这并不明显。

答案 12 :(得分:3)

在我看来,他们被人们过度使用(我在SO上多次讨论这个问题)。

但它们是一个非常有用的结构,因为它们在很小的代码中提供了很多表达能力。

您只需要查看西澳大利亚汽车注册号等示例。 RE将是

re.match("[1-9] [A-Z]{3} [0-9]{3}")

虽然检查这个代码的代码要长得多,无论是简单的9-if语句还是略微更好的循环版本。

我几乎没有在我的代码中使用复杂的RE,因为:

  • 我知道RE引擎是如何工作的,我可以使用领域知识来编写更快的解决方案(9-if变体几乎肯定会比单次RE编译/执行周期更快);和
  • 如果代码在逻辑上被分解并被评论,我发现代码更具可读性。对于大多数RE来说这并不容易(尽管我已经看到了一个允许内联注释的内容)。

已经看到人们建议使用RE来在固定位置提取固定大小的子串。为什么这些人不仅仅使用substring()超出了我的范围。我个人的想法是,他们只是想表明他们有多聪明(但很少有效)。

答案 13 :(得分:2)

言过其实?不,如果您曾经参加过Parsing或Compiler课程,您会理解这就像说数学问题的加法和乘法被夸大了。

这是一个解决解析问题的系统。

一些问题更简单,不需要正则表达式,有些问题更难,需要更好的工具。

答案 14 :(得分:2)

我见过很多人争论一个给定的正则表达式是否正确我开始认为编写一个正则表达式的最佳方法是询问如何在StackOverflow上执行它然后让正则表达式的大师们对抗它进行。


我认为它们在JavaScript中特别有用。传输JavaScript(因此应该很小)并从文本中解释(尽管在使用V8和JIT编译的新浏览器中这种情况正在发生变化),因此良好的内部正则表达式引擎有可能比算法更快。

我想说如果有一种清晰简单的方法来执行字符串操作,请使用字符串操作。但是如果你可以做一个很好的正则表达式而不是编写自己的状态机解释器,那就使用正则表达式。

答案 15 :(得分:2)

在脚本语言(例如Ruby,Python,Perl,JavaScript和Lua)中使用正则表达式是有充分理由的:使用经过仔细优化的正则表达式解析字符串的执行速度比扫描字符串的等效自定义while循环执行得快字符一个字符。对于编译语言(例如C和C ++,以及大多数时候的C#和Java),通常情况恰恰相反:自定义while循环执行得更快。

正则表达式如此受欢迎的另一个原因是:它们以非常紧凑的方式表达了程序员的意图:单行正则表达式可以在10或20行的循环中执行。

答案 16 :(得分:1)

我不会完全避免它们,因为它们有时很方便。但是,重要的是要实现下面的基本机制。根据您的实现情况,搜索可以达到指数运行时间,但由于搜索通常受到一些恒定数量的回溯的限制,因此您可以得到您所见过的最慢的线性运行时间。

如果您想获得最佳答案,则必须检查您的特定实施以及您要搜索的数据。

从内存来看,维基百科有一篇关于正则表达式和基础算法的文章。

答案 17 :(得分:1)

归结为适合工作的正确工具。

我经常听到两个反对正则表达式的论据: 1)它们在计算上效率低下,并且 2)他们很难理解。

老实说,我无法理解这两者是否合法。

1)这在学术意义上可能是正确的。一个复杂的表达式可以在自身上翻倍。这真的很重要吗?如今,服务器处理器每秒可以进行数百万次计算?我已经处理了一些疯狂的表达式,而且我从未看到正则表达式成为瓶颈。到目前为止,它是数据库交互,其次是带宽。

2)辛苦了大约一个星期。最复杂的正则表达式并不比HTML复杂 - 这只是一个熟悉的问题。如果您每3个月需要一次HTML,那么每次都能获得100%的HTML吗?每天与他们合作,他们就像任何其他语言语法一样清晰。

我写了验证软件。 REGEXP是第二天性。每五行代码都有一个正则表达式,对于我的生活,我无法理解为什么人们会对它们做出很大的贡献。我从来没有见过正则表达式减速处理,我甚至看到即使是最沉闷的'程序员'也会选择语法。

Regexp功能强大,高效且实用。为什么要避开它们?

答案 18 :(得分:1)

我同意正则表达式有时会被不恰当地使用。当然,对于非常简单的情况,例如您所描述的情况,以及需要更强大的解析器的情况。

有一个考虑因素是,有时您需要做一些简单的事情,例如测试是否存在问号字符。但通常情况会变得更加复杂。例如,要查找不是前面有空格或行首的问号字符,不是后跟字母数字字符。或者角色可以 问号或西班牙语“¿”(可能出现在单词的开头)。你明白了。

如果预期条件会演变成对String.contains("?")的简单调用不那么简单的事情,那么从一开始就使用非常简单的正则表达式对它进行编码会更容易。

答案 19 :(得分:1)

我经常在IDE中使用正则表达式来快速修复代码。尝试在没有正则表达式的情况下执行以下操作。

glVector3f(-1.0f,1.0f,1.0f); - > glVector3f(center.x - 1.0f,center.y + 1.0f,center.z + 1.0f);

没有正则表达式,这是一种痛苦,但有正则表达式......

s/glVector3f\((.*?),(.*?),(.*?)\)/glVector3f(point.x+$1,point.y+$2,point.z+$3)/g

真棒。

答案 20 :(得分:1)

正则表达式通常比非正则表达式更容易理解,尤其是在具有本机正则表达式的语言中,尤其是在需要使用正则表达式执行其他事务的代码部分中。

这并不意味着他们没有被滥用。 string.match(/ \?/)唯一比string.contains('?')更好的是,如果它对周围的代码更具可读性,或者你知道.contains是用正则表达式实现的

答案 21 :(得分:1)

正则表达式是程序员可以学习的最有用的东西之一,如果您知道如何处理它们,它们可以加快并最小化代码。