为什么字符类比交替更快?

时间:2014-03-02 19:40:11

标签: regex performance perl character-class regex-alternation

似乎使用字符类比例如下例中的交替更快:
[abc] vs (a|b|c)
我听说过它被推荐并且使用Time::HiRes进行简单的测试我验证了它(慢了~10倍) 如果捕获括号产生差异,也使用(?:a|b|c)不会改变结果 但我不明白为什么。我认为这是因为回溯,但我在每个位置看到它的方式有3个字符比较所以我不确定回溯是如何影响交替的。这是实施交替性质的结果吗?

2 个答案:

答案 0 :(得分:11)

这是因为交替之间的“OR”构造| 回溯:如果第一次交替不匹配,引擎必须在指针位置移动之前返回交替,继续匹配下一轮交替;而字符类可以顺序前进。在禁用优化的正则表达式引擎上查看此匹配:

Pattern: (r|f)at
Match string: carat

alternations

Pattern: [rf]at
Match string: carat

class


但简而言之,引擎优化此(单个字面字符 - >字符类)的事实已经是一个不错的提示,即交替效率低下。

答案 1 :(得分:7)

因为像[abc]这样的角色类是不可减少的并且可以进行优化,而像(?:a|b|c)这样的替代也可能是(?:aa(?!xx)|[^xba]*?|t(?=.[^t])t)

作者选择了 not 来优化正则表达式编译器,以检查交替的所有元素是否都是单个字符。

“检查下一个字符是否在此字符类中”“检查字符串的其余部分是否匹配这些正则表达式中的任何一个”