正則表達式匹配回溯: 一.基本概念: NFA引擎的正則表達式會依次處理各個子表達式或者組成元素,遇到需要在兩個都可能進行成功匹配的子表達式或者組成元素之間進行選擇的時候,會首先選擇其一,同時會記錄另一個的狀態,以備后面使用。 注意:這里所說的子表達式並非只有用小括號括起來的表達式,而是正則表達式中的任意匹配單元。 二.需要回溯的情況: 無論是哪一種選擇,如果本身匹配成功,而且正則表達式余下的部分也能夠成功匹配的話,那么整個匹配就成功了,如果正則表達式當前選擇或者后面的部分無法匹配成功,那么正則表達式引擎會回溯到之前作出選擇的地方,然后選擇其他備用的分支繼續匹配。 三.回溯演示: 下面對正則表達式回溯通過一個實例代碼進行一下分解,建議首先參閱正則表達式匹配原理一章節。 代碼實例如下: |
var str="I love antzone"; var reg=/ant(tone|moze|zone)/g; console.log(str.match(reg));
以上正則表達式可以匹配字符串中的"antzone"。在正則表達式中有分支選項,這里就會用到回溯了。
下面進行一下分解:
首先正則表達式字符串中的字符"a"會獲得控制權,從位置0處開始匹配,它並不能夠匹配字符"a",然后正則引擎推動字符"a"從下一個位置開始匹配,一直到字符串中的字符"a"才能夠匹配成功,然后正則表達式的控制權傳給字符"n",匹配字符"n"成功,然后控制權傳遞給字符"t",匹配字符"t"成功。這個時候后面會遇到三個分支,正則引擎會選擇其中之一進行匹配,其他的則作為備用,首先選擇"tone"進行匹配,匹配失敗,但是此次失敗並不說明這個匹配會失敗,因為還有可能匹配成功的備用選項存在,這個時候正則表達式會回溯到"tone"開始匹配的位置,再使用"moze"進行匹配,最后最后一個選項分支可以匹配成功。
可能上面的稍顯復雜了,下面來個簡單的再回頭看上面的可能就容易理解了。
代碼如下:
var str="ac"; var reg=/a(d|c)/g; console.log(str.match(reg));
圖示如下:
<ignore_js_op>
分解如下:
首先正則表達式中的字符"a"獲得控制權,從位置0處開始匹配,它可以匹配字符串中的字符"a",然胡控制權讓渡給"(d|b)",這是一個選擇分支,首先使用第一個選項"d"從位置1處開始匹配,並且另一個選項"b"作為一個備選狀態。字符"d"並不能夠匹配字符"b",所以進行回溯,也就是再回到位置1處使用備選狀態進行匹配。回溯原理大致如此,只是有的復雜有的簡單而已。
