非贪婪搜索和否定字符集之间的区别

时间:2014-07-10 21:02:23

标签: regex

这两种正则表达式模式之间是否存在差异(假设单行模式已启用):a.*?ba[^b]*b?在性能方面呢?

2 个答案:

答案 0 :(得分:4)

a.*?b必须检查每个消费角色是否与模式匹配(即下一个角色是b)。这称为回溯。

使用字符串a12b,执行将如下所示:

  • 消耗a
  • 使用以下0个字符。下一个是b吗?否。
  • 使用以下字符(a1)。下一个是b吗?否。
  • 使用以下字符(a12)。下一个是b吗?是的!
  • 消耗b
  • 匹配

a[^b]*b在没有问自己问题的情况下会消耗任何不是b的内容,并且由于这个原因,对于更长的字符串会更快。

使用字符串a12b,执行将如下所示:

  • 消耗a
  • 消费后面的任何不是b的内容。 (a12
  • 消耗b
  • 匹配

RegexHero有一个基准测试功能,可以使用.NET正则表达式引擎进行演示。

除性能差异外,它们与您示例中的相同字符串匹配。

然而,有些情况下两者之间存在差异。在字符串aa111b111b

(?<=aa.*?)bb匹配,(?<=aa[^b]*)b仅与第一个匹配。

答案 1 :(得分:1)

我测试了你的两个正则表达式,将它们命名为:

NONGREEDY = /a.*?b/;
GREEDY = /a[^b]*b/;

我将负正则表达式命名为GREEDY,但只是名称。

您可以在JsPerf上查看test-non-greedy-vs-greedy-performance并运行测试以自行查看。随意修改字符串以执行不同的测试用例。

您可以检查人员添加的不同测试,基准测试结果因输入字符串而异。

以下测试用于字符串: ab

enter image description here

enter image description here

以下测试用于字符串: axb enter image description here

以下测试用于字符串: afdkjsklfjsdlkfjsdlkfjsdlkjflskdjflsdfjjflksdjfb enter image description here

经过这些测试后,性能似乎会因您要解析的字符串而异。

希望这个测试可以帮助回答这个问题。