溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

正則引擎分為幾種?

發(fā)布時間:2020-05-27 09:03:31 來源:億速云 閱讀:394 作者:Leah 欄目:編程語言

今天小編給大家分享的是正則引擎的詳細介紹,相信大部分人都不太了解,為了讓大家更加了解,小編給大家總結了以下內(nèi)容,話不多說,一起往下看吧。

正則引擎
DFA
傳統(tǒng)型NFA
POSIX NFA
NFA范圍更廣,例如 JAVA, PHP, Ruby, .NET... 你是看不起我javascript所以才不列入的嗎?
使用DFA的是flex, MySQL, lex, awk大部分版本… 實話說,除了mysql,都沒聽過。不過不用在意!

兩個引擎的區(qū):
NFA 更注重表達式
DFA 文本主導
  通過書中里例子說,NFA 用表達式來匹配文本,而 DFA 是文本來匹配文表達式。當寫好一個正則之后,NFA 是先檢查表達式,同時檢查文本是否匹配這個表達式。而 DFA 則是先掃描文本,然后處理表達式中的所有匹配可能,如果匹配失敗,就將這條可能的線,淘汰。所以這里衍生一個概念就是回溯,NFA 有回溯,而 DFA 沒有。

知識點
  作為一個菜鳥,正則表達式一直是書到用時方恨少的角色。平時都是能抄則抄,不能抄的時候干著急,只能用 substr, indexOf, chatAt等等的方法實現(xiàn)功能,既不優(yōu)雅也不夠裝逼。上網(wǎng)學習也都是菜鳥教程,W3school。然后下面說一下以上兩個基礎教程里沒說到的知識點。

  括號捕獲與反向引用
  當你在正則表達式里使用了 (),在表達式匹配時,它能記住或者說緩存括號內(nèi)匹配的結果,從而可以拿到括號內(nèi)的結果,可以重復使用或者只需要括號內(nèi)的結果,來剔除不需要的匹配內(nèi)容。

// 我們經(jīng)常會用 match 方法來匹配字符串,結果是一個數(shù)組,而不是最后的匹配結果,為什么呢?看下面的例子
"abc".match(/(a)(b)(c)/) // ["abc", "a", "b", "c"]
"abc".match(/abc/) // ["abc"]
  可以看到,括號會緩存括號里匹配的內(nèi)容,單獨列出來,那么怎么拿到括號內(nèi)的內(nèi)容呢,而不是通過 match 返回的結果拿,因為有時候我們需要在表達式里使用捕獲的值,從而達到匹配重復的內(nèi)容。這部分就叫反向引用。

"abc-abc-cba".replace(/(a)(b)c-\1\2/, '') // c-cba
"abc-abc-cba".replace(/(a)(b)c/g, '$1$2') // ab-ab-cba
RegExp.$1 // a
RegExp.$2 // b
  這里展示了兩種使用反向引用的方法,一種是在表達式內(nèi)通過 \1\2 的形式拿到兩個緩存的值,一種是使用 $1$2的形式拿到。因為正則是從左開始匹配的,所以 (a) 就是第一個捕獲的匹配值,所以他是\1 或是 $1,以此類推。

  非捕獲型括號
  上面說了括號會捕獲值,一般來說這樣會影響性能,或者你會用到括號來做分組,但是不想捕獲的情況,(?:)非捕獲型括號就是這么用的,那么重寫一下上面的例子。

"abc-abc-cba".replace(/(a)(?:b)c-\1\2/, '') // 匹配失敗了,因為\2不存在
"abc-abc-cba".replace(/(a)(?:b)c-\1/, '') // bc-cba
RegExp.$1 // a
RegExp.$2 // ""
  環(huán)視

類型  正則表達式
肯定逆序環(huán)視  ?<=
否定逆序環(huán)視  ?<!
肯定順序環(huán)視  ?=
否定順序環(huán)視  ?!
  ?= 和 ?! 在菜鳥和w3school 里有簡單的提及,菜鳥里還提到這兩個還能重寫捕獲,但是 ?<= 和 ?<! 并沒有提及。

  寫幾個 demo 表示一下:

// 找一個字母 a ,它緊跟在 b 前面
"abac".replace(/a(?=b)/g, '') // bac

// 找到一個字母 a ,它緊跟在一個不是 b 的字母前面
"abac".replace(/a(?!b)/g, '') // abc

// 接著是逆序環(huán)視
// 找到一個字母 a ,它跟在 b 后面
"abac".replace(/(?<=b)a/g, '') // abc

// 找到一個字母 a ,他不跟在 b 后面
"abac".replace(/(?<!b)a/g, '') // bac

// 一個有趣匹配
// 在 a 和 b 之間插入一個 ","
"abac".replace(/(?<=a)(?=b)/g, ",") // a,bac
  可以看出,環(huán)視是要和捕獲括號一起用的,并且不會占用匹配字符,他只是檢查表達式是否匹配。所以這就是重寫捕獲了。

忽略優(yōu)先量詞
  量詞匹配一般有三種 、 +、?。然而還可以寫作, ? 或 +? ,使匹配結果導向完全不同的結果。例子:

"abc-aaa-abc-abc".replace(/abc-.*-abc/, '') // ""

"abc-aaa-abc-abc".replace(/abc-.?-abc/, '') // "-abc"
  
? 忽略優(yōu)先會先忽略當前匹配的值,先匹配后面的 -abc,如果匹配失敗,再匹配自己,而 會優(yōu)先匹配自己,等匹配結束之后,再從后面一點點吐出,回來匹配量詞后面的表達式。從而造成以上不同的結果。知道這個之后,就不會再傻傻的把 和 ? 分開解讀了。當然,具體情況具體分析,到底使用哪個。

回溯
回溯應該算是正則里的性能殺手了吧。如果表達式寫的不好,造成過度的災難性回溯,會導致執(zhí)行時間指數(shù)級增長。

看完上述內(nèi)容,你們對正則引擎大概了解了嗎?如果想了解更多相關文章內(nèi)容,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI