我们应该避免使用正则表达式,因为它很慢。相反,我们应该使用字符串操作是否存在两种情况都可以使用但regexp更好的情况?
答案 0 :(得分:4)
您应该使用适当的工具来完成工作。这意味着,你不应该避免正则表达式,你应该在必要时使用它。
如果您只是搜索固定的字符序列,请使用字符串操作。
如果您要搜索模式,请使用正则表达式。
示例强>
搜索“Foo”这个词。使用字符串操作它也会找到 “Foobar”,这样可以吗?不,那么可能会搜索“Foo”,但随后 它不会找到“Foo”和“Foo。”
使用正则表达式没问题,你可以匹配单词边界/ \ mFoo \ M /和 这个正则表达式不会很慢。
我认为这种负面形象来自catastrophic backtracking等特殊问题。
最近有一个例子(catastrophic-backtracking-shouldnt-be-happening-on-this-regex),这种行为是出乎意料的。
<强>结论强>
正则表达式必须精心设计,如果不是那么表现可能是灾难性的。但是如果使用错误的算法,那么普通代码也会发生同样的情况。
对于小型工作来说,使用正则表达式几乎不会成为问题,如果你的任务更大并且必须经常重复,那就做一个基准测试。
根据我自己的经验,我正在分析真正的大文本文件(几百MB)并使用正则表达式来查找我感兴趣的行,并且由于正则表达式我没有遇到性能问题。
答案 1 :(得分:3)
正则表达式(REs)是一个了不起的锤子。他们可以优雅地解决一些问题,还有更多的蛮力,但它不会很漂亮。如果你足够了解RE,可以解决一些问题,但是有更好的解决方案可用(例如,适合string map
的东西)
string match
- 或者globbing - 可以被认为是正则表达式的简化版本。 glob模式通常比同等的正则表达式短(字符类是一个例外 - ER支持它们,你需要拼写它们才能拼出它们)。我不知道性能如何不同;由于逻辑更简单,我希望string match
在等效模式上略快一些,但time
比预期更可靠。
对于RE更易于使用的特定情况,从上下文提取子字符串与简单字符位置提取子字符串就是一个很好的例子。或者匹配几种替代方案中的一种。
我的经验法则是使用最简单的方法。如果那是string match
,那就太好了。如果模式似乎过于复杂,请转到正则表达式,并且很高兴您可以选择。
答案 2 :(得分:2)
我能给出的最好的建议,以及我自己使用的建议是,只有当一个更简单的解决方案不起作用时才使用正则表达式。
如果您可以使用简单的字符串匹配,或使用glob模式,请使用它们。只有当那些无法工作时才应该使用正则表达式。
为了解决您的具体问题,我会说,不,没有时间您可以使用其中任何一个,但正则表达式是更好的选择。也许有一个我没想到的优势,但总的来说,更简单的解决方案总是更好。
答案 3 :(得分:1)
我特别不了解Tcl,但通常可以说如果你正在寻找精确的文本匹配(例如,找到以#define
开头的所有行),那么字符串操作会更快。但是,如果您正在寻找模式(例如,所有包含以c
开头且以t
结尾的单词的行),则正则表达式是正确的工具( \bc\w*t\b
对于这个来说是一个很好的正则表达式 - 如果你必须自己写这个,那么将它与你需要的程序逻辑进行比较。
即使在这种情况下正则表达式较慢,在执行速度方面也无关紧要,但是当需要更改匹配逻辑时,这很重要(哦,现在我们我需要查找以c
开头且以t
结尾但仍包含至少两个a
且无x
- &gt; \bc(?=\w*a\w*a)(?!\w*x)\w*t\b
)的字词
大多数正则表达式引擎不想去的地方是递归(匹配嵌套标签,嵌套括号和所有这些)。这就是解析器进入图片的地方。
答案 4 :(得分:1)
正则表达式匹配是一种字符串操作。虽然它没有一些更基本的操作那么快,但它的功能也非常强大。它也更难使用,特别是如果你还不知道RE的基本语法,但这并不是避免它们的理由。但是,用一组基本字符串操作替换正则表达式只会导致程序变得非常长:有时,您只需要复杂的操作。
Tcl做了很多事情,使RE操作更有效率。值得注意的是,它检测到特别简单的RE并将它们转换为类似于glob的匹配(如在string match
中),这些匹配更快但功能更弱,并且它可以执行许多操作来缓存RE的编译形式,以便匹配具有减少开销。它还使用自动机理论匹配引擎,在匹配时间内减少意外(以更多时间编译RE的成本为代价)。
简而言之,不要躲避它们。适当时使用它们。 (如果你对速度有疑问,请time
。)
答案 5 :(得分:0)
regexp
也称正则表达式用于匹配许多不同的字符串,可能非常复杂,甚至可以验证特定的输入。
string match
仅允许*
和?
等通配符以及{regexp中{{1}}的基本字符分组。
你可以在这里阅读:http://www.tcl.tk/man/tcl8.5/TclCmd/string.htm#M40
这里解释了正则表达式可以用一些例子做的基本指南:http://www.regular-expressions.info/
所以简而言之:如果你不需要regexp甚至不太了解它,我建议你不要使用它。如果您只想比较两个字符串的相等性,请使用[]
。