正则表达式笔记(四)-回溯法原理

168 阅读1分钟

[JS正则迷你书作者](老姚 的个人主页 - 动态 - 掘金 (juejin.cn))

[JS正则迷你书](《JavaScript 正则表达式迷你书》问世了! - 知乎 (zhihu.com))

回溯法原理-深度优先搜索算法

没有回溯的匹配

图片截自正则迷你书

有回溯的匹配

图片截自正则迷你书

var regex = /ab{1,3}bbc/
var string = "abbbc"

图片截自正则迷你书

var regex = /".*"/
var string = '"abc"de'

图片截自正则迷你书

图中省略了尝试匹配双引号失败的过程。可以看出.*是非常影响效率的。

为了减少一些不必要的回溯,可以把正则修改为

/"[^"]*"/

本质上就是深度优先搜索算法

常见的回溯形式

贪婪量词

惰性量词

惰性量词就是在贪婪量词后面加个问号。表示尽可能少的匹配。虽然惰性量词不贪,但也会有回溯的现象。

图片截自正则迷你书

分支结构

/^(?:can|candy)$/

图片截自正则迷你书

总结

贪婪量词“试”的策略是:买衣服砍价。价钱太高了,便宜点,不行,再便宜点。

惰性量词“试”的策略是:卖东西加价。给少了,再多给点行不,还有点少啊,再给点。

分支结构“试”的策略是:货比三家。这家不行,换一家吧,还不行,再换。

既然有回溯的过程,那么匹配效率肯定低一些。相对谁呢?相对那些 DFA 引擎, DFA 是“确定型有限自动机”的简写。

而 JavaScript 的正则引擎是 NFA,NFA 是“非确定型有限自动机”的简写。

大部分语言中的正则都是 NFA,为啥它这么流行呢?

答:你别看我匹配慢,但是我编译快啊,而且我还有趣哦。