正则表达式匹配原理
正則表達式匹配原理:
本章節將會簡單的介紹一下正則表達式匹配原理,這將有助于書寫更為有效率的正則表達式,而不僅僅能夠完成匹配任務。
一.關于正則表達式引擎:
正則引擎大體上可分為不同的兩類:DFA和NFA。
1.DFA是Deterministic finite automaton的縮寫,確定型有窮自動機。
2.NFA是Non-deterministic finite automaton的縮寫,非確定型有窮自動機。NFA又可以分為兩類:
1): Traditional NFA,傳統型非確定有窮自動。
2): POSIX NFA,符合標準的非確定型有窮自動機。
DFA引擎不需要進行回溯,所以匹配效率一般情況下要高,但是它并不支持捕獲組,于是也就不支持反向引用和$這種形式的引用。
POSIX NFA是指符合POSIX 標準的NFA引擎,它的主要特點是提供longest-leftmost匹配,也就是說在找到最左側最長匹配之前,它將繼續回溯,此種引擎對非貪婪模式不支持。
當前大多數語言都是使用傳統型NFA正則引擎,因為它更為強大靈活。
二.字符串的組成:
想要真正理解正則表達式的匹配原理,那么首先就要知道在正則表達式眼中,字符串是由哪些成分構成的,圖示如下:
上面的圖片得出,字符串不但由字符組成,還包括字符之間的位置。對于字符串"antzone"而言,它是由7個字符和8個位置構成。
三.零寬和占有字符表達式:
在正則表達式中,如果子表達式匹配到的是字符內容,而非位置,并且會被保存到匹配結果中,那么這個子表達式是占有字符的。如果子表達式匹配的是位置,或者匹配的內容不被保存在最終結果中,那么就認為這個子表達式是零寬的。
占有字符是互斥的,零寬度是非互斥的。也就是一個字符,同一時間只能由一個子表達式匹配,而一個位置,卻可以同時由多個零寬度的子表達式匹配。
注意:這里所說的子表達式并非只有用小括號括起來的表達式,而是正則表達式中的任意匹配單元。
四.控制權的傳動:
正則表達式當開始匹配的時候,一般是由一個子表達式獲取控制權,從字符串中的某一個位置開始嘗試匹配,一個子表達式開始嘗試匹配的位置,是從前一子表達匹配成功的結束位置開始的,看下面的例子:
(子表達式一)(子表達式二)
如果子表達式一是零寬度的,那么它的匹配起始位置和結束位置是同一個位置,如果位置是0,那么子表達式二將從位置0進行匹配。
如果子表達式一是占有字符的,開始匹配位置0,結束匹配位置是4,那么子表達式二的開始匹配位置就是4。
五.正則表達式匹配分解:
分解演示一:
1.將要進行匹配的字符串:"antzone"。
2.正則表達式:/zone/。
匹配過程如下:
首先由正則表達式中字符"z"取得控制權,然后去嘗試匹配字符串中的第一個字符"a",匹配失敗,則繼續嘗試第二個字符"n"依然會失敗,直到字符"z",匹配成功,這樣控制權由正則表達式中的字符"z"傳遞給字符"o",由于字符"z"已經被匹配,所以字符"o"將會從位置4開始匹配,由"o"來匹配"o",匹配成功,這樣依次傳遞下去,最終正則表達式匹配成功,匹配結果為"zone"。
實例如下:
var str="antzone"; var reg=/zone/; console.log(str.match(reg));
分解演示二:
1.將要進行匹配的字符串:"antzone"。
2.正則表達式:/an?t/。
匹配過程如下:
首先由正則表達式中的元字符取得控制權,開始去嘗試匹配字符串"antzone",它匹配的是單詞邊界位置,匹配成功后,控制權交給正則表達式字符"a",由于""是零寬的,所以"a"從位置0開始匹配,匹配字符"a"成功,然后將控制權交給"n?",由于“?”是匹配優先量詞(同時記錄一個備選狀態,如果匹配不成功則進行回溯),所以會先嘗試進行匹配,能夠成功"n",控制權然后交給字符"t",也能夠匹配成功,匹配結果為:"ant"。
實例如下:
var str="antzone"; var reg=/an?t/; console.log(str.match(reg));
總結
- 上一篇: 《大侠立志传》破庙攻略一览
- 下一篇: Sanic官翻-部署