日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

JavaScript正則表達(dá)式這幾個細(xì)節(jié)你真的知道?

瀏覽:107日期:2023-11-16 14:47:11
前言

粗淺的編寫正則表達(dá)式,是造成性能瓶頸的主要原因。如下:

var reg1 = /(A+A+)+B/; var reg2 = /AA+B/;

上述兩個正則表達(dá)式,匹配效果是一樣的,但是,效率就相差太遠(yuǎn)了,甚至在與少量字符串匹配時,reg1就會造成你瀏覽器卡死。

不信?我們可以測試下。

首先,我們聲明一個字符串變量str,同時賦予一個包含20個A的字符串給str,采用match方法與上述reg1、reg2進(jìn)行匹配測試,如下:

var str = ’AAAAAAAAAAAAAAAAAAAA’;str.match(reg1);str.match(reg2);

在瀏覽器中運行該段代碼,發(fā)現(xiàn)一切正常嘛。

然而,隨著,我們不斷向變量str中添加A后,重復(fù)測試,在某一刻(取決于你的瀏覽器),reg1就會讓我們的瀏覽器掛起,但,回頭看看最終的str字符串長度,卻還不到50。而,reg2卻安然無恙。

心里有一絲疑問,是什么造成了它們?nèi)绱司薮蟮牟顒e?以后我們在寫正則表達(dá)式時,又該如何避免防范這類問題呢?

那么,接下來,我們就有必要深入理解JavaScript正則表達(dá)式的內(nèi)部執(zhí)行原理了。

如果,在此你還不是很了解正則表達(dá)式,那么可以參考如下兩篇博客后,再前來,小生在此等候。

正則表達(dá)式工作原理

為了高效的使用正則表達(dá)式,理解它們的工作原理是很重要的。

具體如下:

Step1.編譯

當(dāng)我們創(chuàng)建一個正則表達(dá)式(字面量或者RegExp對象)后,瀏覽器會檢查該正則的模板是否符合標(biāo)準(zhǔn),然后將其轉(zhuǎn)化成內(nèi)部代碼,用于執(zhí)行匹配工作。

所以,如果我們將正則表達(dá)式賦予一個變量,可以避免重復(fù)執(zhí)行該 ‘編譯’ 步驟。

Step2.設(shè)置開始位置

當(dāng)我們使用Step1中編譯后的正則表達(dá)式時,首先它將確定從目標(biāo)字符串中什么位置進(jìn)行匹配。通常,是目標(biāo)字符串的起始位置,或者由正則表達(dá)式的lastIndex屬性指定。

但是,當(dāng)它從Step4(匹配失敗)中返回時,該位置則為匹配失敗的位置的下一個位置。

Step3.正則匹配

當(dāng)經(jīng)歷Step2后,正則表達(dá)式將從指定位置,從左到右,與目標(biāo)字符串,逐個匹配。若,正則表達(dá)式在匹配過程中,遇到某個字元匹配不了時,它不會立即失敗,而是嘗試回溯到最近一個決策點,然后在剩余選項中選擇一個,以求繼續(xù)能匹配。

Step4.匹配結(jié)果

當(dāng)經(jīng)歷Step3后,發(fā)現(xiàn)能與正則匹配成功的子字符串,那么就匹配成功。如果,經(jīng)歷了Step3后,發(fā)現(xiàn)沒有能與正則匹配的子字符串,那么,它將回到Step2,繼續(xù)。只有當(dāng)目標(biāo)字符串中的每個字符(以及最后一個字符后面的位置)都經(jīng)歷了Step3后,仍沒有找到匹配項,才宣布失敗。

下面就舉個例子,使我們更透徹地明白以上4步。

如下:

var reg = /A(B|C)D/g; var str = ’ABCACD’;reg.exec(str);

① 首先,瀏覽器將解析reg正則表達(dá)式(Step1)。

② 然后,由于是首次匹配,所以確認(rèn)開始位置即為字符串起始位置(Step2)。

③ 首先由正則的第一個字元A與字符串起始位置字符A匹配,成功,并在之后的位置記錄一個決策點,因為后面有分支嘛;然后由 (B|C)分支中的B選項去匹配字符串的B,發(fā)現(xiàn)匹配;然后再由正則下一個字元D去匹配目標(biāo)字符串第三個字符C,發(fā)現(xiàn)不匹配,但是并沒有放棄,而是回溯,查看是否有決策點,發(fā)現(xiàn)有,回溯到就近一個決策點(字符串首字母A之后的那個位置上),嘗試?yán)玫诙€分支選項C去匹配字符串第二個字符B,發(fā)現(xiàn)不匹配,回溯,查詢是否還有其他分支選項,發(fā)現(xiàn)沒有,然后宣布該次失敗(Step3)。

④ 經(jīng)歷Step3后,發(fā)現(xiàn)沒有與正則匹配的子字符串,但是,與之匹配的目標(biāo)字符串的匹配位置并不是最后一個位置,所以,回到Step2,從目標(biāo)字符串的下一個位置(即,字符串首字母A之后的那個位置上)開始匹配。首先由正則表達(dá)式的第一個字元A與目標(biāo)字符串B匹配,不成功,又無回溯點,故而,進(jìn)入Step4,判斷是否是最后一個位置,發(fā)現(xiàn)不是,又跳到Step2中繼續(xù)。

⑤ 就這樣一步一步,來到了目標(biāo)字符串的第四個位置,首先A去與目標(biāo)字符串的第三個字符A匹配,成功;接下來就是由分支(B|C),去匹配C,首先由分支中的第一個選項B去與C匹配,發(fā)現(xiàn)沒有成功,回溯到就近一個決策點,嘗試?yán)玫诙€分支選項C匹配,成功,緊接著D也成功了。

⑥ 匹配成功,并將lastIndex置為6。

JavaScript正則表達(dá)式這幾個細(xì)節(jié)你真的知道?

回溯

上述 “正則表達(dá)式工作原理” 一小節(jié),Step3中的回溯我們是一筆帶過的。但是,可不要忽略了,回溯在正則中是非常重要的,如果理解得不明白,我們在編寫正則時,很容易造成回溯失控。

下面我們就來一起看看回溯在正則表達(dá)式中的運用。

正則表達(dá)式中有兩種情況,會制造回溯點:

-分支(通過|操作符)

-量詞(諸如*,+?,或者{…})

下面我們就分別舉例來看看。

分支和回溯

對于分支,詳見 ‘正則表達(dá)式工作原理’ 小節(jié)中Demo。

量詞和回溯

在量詞中,有貪婪量詞(諸如*,+)和非貪婪量詞(諸如*?,+?)之分。所以回溯形式對于它們而言也就有差別咯。我們首先寫個demo看看貪婪量詞是怎么回溯的。

Demo如下:

var reg = /w*D/g; var str = ’MonkyDorie!’;reg.exec(str);

就上述貪婪模式匹配流程如下:

提醒:正則表達(dá)式reg中w表示匹配“字母、數(shù)字或下劃線”,*這個貪婪量詞表示重復(fù)匹配零次或者多次,由于是貪婪量詞,故而它會盡可能多的匹配。

① 首先,正則中的w*與目標(biāo)字符串匹配,會一直匹配到‘!’之前,即’MonkyDorie’,并且,每個匹配位置都會記錄一個決策點,便于回溯。

② 然后,由正則中的剩余字元D與字符串中!匹配,匹配失敗;但是,它并沒有放棄(因為在此之前,記錄了決策點),而是回溯到就近一個決策點(字符e的前一個位置),然后正則D與字符e匹配,匹配失敗;再回溯到就近一個決策點(字符i的前一個位置),然后正則D與字符i匹配,匹配失敗;就這樣一直回溯到字符D的前一個位置時,正則D與字符D匹配,匹配成功,并置lastIndex為6。

好了,這就是上述貪婪匹配流程。

隨后,我們將上述Demo中的正則表達(dá)式,稍微調(diào)整下,在*后面加上?,變成非貪婪模式,看看非貪婪量詞是怎么回溯的。

Demo如下:

var reg = /w*?D/g; var str = ’MonkyDorie!’;reg.exec(str);

就上述非貪婪模式匹配流程如下:

提醒:正則表達(dá)式reg中w表示匹配“字母、數(shù)字或下劃線”,*?是個非貪婪量詞,也表示重復(fù)匹配零次或者多次,但是由于是非貪婪量詞,故而它會盡可能少的匹配。

首先,正則中的w*?會選擇匹配零個字符(盡可能少的匹配),并將第一個位置(字符M的前一個位置)記錄一個決策點,繼而輪到字元D與字符串字符M匹配,匹配失敗;回溯到就近一個決策點(字符M的前一個位置),然后w*?選擇匹配一個字符M,并記錄一個回溯點(第二個字符o的前一個位置),繼而輪到字元D與字符串字符o匹配,匹配失敗;回溯到就近一個決策點(字符o的前一個位置),就這樣一步一步,當(dāng)w*?選擇匹配五個字符Monky時,繼而輪到字元D與字符串字符D匹配,匹配成功,并置lastIndex為6.

上述兩Demo,對比圖如下:

JavaScript正則表達(dá)式這幾個細(xì)節(jié)你真的知道?

利用前瞻和后向引用避免回溯

正如上述 ‘回溯’ 小節(jié)中談到,重復(fù)量詞和分支會記錄決策點,引起回溯。但是,如果在實際需求中,我們不想讓它們記錄決策點呢—因為回溯太多就會導(dǎo)致回溯失控,影響性能,正如我們在 ‘前言’ 中看到的那樣。

一些正則表達(dá)式引擎,支持一種叫做原子組的屬性。原子組,寫作(?>…),省略號表示任意正則表達(dá)式模板。存在原子組中的正則表達(dá)式組中的任何決策點都將被丟棄。利用原子組,我們就可以在必要時,消除由重復(fù)量詞和分支記錄的決策點了。

但,在JavaScript中不支持原子組,怎么辦呢?

我們可以利用前瞻來模擬原子組,但是,前瞻在整個匹配過程中,是不消耗字符的,它只是檢查自己包含的模板是否能在當(dāng)前位置匹配。然而,我們又可以利用后向引用解決此問題,如下:

(?=(pattern to make atomic))1

好了,針對 ‘利用前瞻和后向引用避免回溯’ 一節(jié),我們寫個Demo,自我測試下:

var str = ’ABCDM’; //目標(biāo)字符串 var reg1 = /w*M/; //貪婪模式 var reg2 = /(?=(w*))1M/; //貪婪模式,使用前瞻和后向引用 var reg3 = /w*?M/; //非貪婪模式 var reg4 = /(?=(w*?))M/; //非貪婪模式,使用前瞻和后向引用

對于以下匹配結(jié)果,各位看官答對否:

str.match(reg1);str.match(reg2);str.match(reg3);str.match(reg4);

來自:http://www.cnblogs.com/giggle/p/5990486.html

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
都市激情国产精品| 国产成人久久精品一区二区三区| 日韩毛片在线| 99精品一区| 亚洲一区二区免费看| 久久国产99| 91精品福利观看| 国产精品啊啊啊| 97精品国产| 影音先锋国产精品| 日韩一级网站| 日本成人精品| 精品一区二区三区视频在线播放| 夜鲁夜鲁夜鲁视频在线播放| 国产一区日韩一区| 四虎精品永久免费| 免费一区二区三区在线视频| 日韩一区二区在线免费| 夜夜嗨一区二区| 91精品国产一区二区在线观看| 欧美成a人片免费观看久久五月天| 四虎国产精品免费观看| 午夜欧美精品| 日韩av电影一区| 桃色av一区二区| 久热re这里精品视频在线6| 国产日韩欧美中文在线| 免费福利视频一区二区三区| 水蜜桃久久夜色精品一区的特点| 国产精品综合色区在线观看| 久久理论电影| 日韩av二区在线播放| 群体交乱之放荡娇妻一区二区| 久久国产成人| 国产中文字幕一区二区三区| 丝袜美腿亚洲一区二区图片| 国产精品久久久久蜜臀| 一区二区电影在线观看| 日韩在线二区| 国产色99精品9i| 五月天激情综合网| 国产精品超碰| 日韩中文字幕一区二区三区| 国产资源在线观看入口av| 蜜桃视频第一区免费观看| 福利一区在线| 日本一区免费网站| 欧美综合另类| 精品资源在线| 日韩精品一级中文字幕精品视频免费观看 | 91免费精品| 亚洲欧洲专区| 91精品综合| 日韩av在线播放中文字幕| 久久久夜夜夜| 精品中文在线| 91精品一区| 视频一区视频二区在线观看| av综合电影网站| 国产极品一区| 日本aⅴ精品一区二区三区| 国产综合色产| 波多视频一区| 国产一区二区视频在线看| 日韩不卡一区二区三区| 日韩视频在线一区二区三区| 水蜜桃精品av一区二区| 国产精品久一| 久久国产精品99国产| 日本午夜大片a在线观看| 国产高清亚洲| 欧美日本不卡高清| 日韩精品一区二区三区av| 亚洲专区欧美专区| 激情综合自拍| 91tv亚洲精品香蕉国产一区| 精品入口麻豆88视频| 国产精品4hu.www| 国产日韩一区二区三区在线播放| 亚洲不卡视频| 亚洲啊v在线免费视频| 亚洲一区二区三区四区电影| 日韩视频一区| 亚洲精品极品少妇16p| 久久黄色影院| 久久高清免费| 99久久婷婷| 91精品国产调教在线观看| 国产精品99一区二区三| 电影91久久久| 色在线中文字幕| 国产 日韩 欧美一区| 日韩专区精品| 激情婷婷亚洲| 最新亚洲激情| 丝袜亚洲精品中文字幕一区| 羞羞答答国产精品www一本| 亚洲自啪免费| 久久午夜视频| 亚洲一区久久| 黄页网站一区| 天堂成人免费av电影一区| 日av在线不卡| 婷婷精品久久久久久久久久不卡| 在线观看一区| 日韩av一区二区在线影视| 国产日韩精品视频一区二区三区| 欧美国产专区| 国产精品yjizz视频网| 日韩不卡免费高清视频| 欧美大黑bbbbbbbbb在线| 欧美在线综合| 青草综合视频| 成人亚洲精品| 涩涩av在线| 影音先锋久久| 欧美日本一区| 日韩大片在线| 香蕉久久久久久久av网站| 天堂久久一区| 久久99偷拍| 久久免费国产| 在线视频精品| 911精品国产| 精品国产a一区二区三区v免费| 美女一区网站| 婷婷综合激情| 日韩在线网址| 久久久久九九精品影院| 久久av资源| 日韩精品欧美激情一区二区| 久久福利影视| 国产精品第一国产精品| 色在线视频观看| 亚洲免费在线| 欧美精品成人| 国产亚洲在线观看| 国产精品国码视频| 欧美三级网址| 亚洲图片久久| 91欧美在线| 香蕉成人久久| 久久精品二区亚洲w码| 亚洲二区精品| 亚洲一区国产| 国产剧情一区二区在线观看| 国产精品蜜芽在线观看| 999在线观看精品免费不卡网站| 亚洲+小说+欧美+激情+另类| 精品三级av| 美日韩精品视频| 久久亚洲黄色| 日韩在线卡一卡二| 中文字幕人成乱码在线观看| 午夜精品亚洲| 国产福利一区二区三区在线播放| 四虎影视精品| 91麻豆精品激情在线观看最新| 日韩亚洲一区在线| 亚洲乱码视频| 免费在线小视频| 日韩精品第一| 成人羞羞视频播放网站| 日韩精品免费一区二区夜夜嗨| 精品捆绑调教一区二区三区 | 久久麻豆视频| 国产视频亚洲| 成人一区而且| 少妇高潮一区二区三区99| 久久久精品午夜少妇| 国产精品久久久久久久久免费高清| 香蕉视频亚洲一级| 日韩av不卡一区二区| 欧美日韩一区二区综合| 国产精品mv在线观看| 免费精品视频在线| 999精品色在线播放| 久久av免费| 亚洲aa在线| 激情婷婷综合| 福利一区和二区| 国产日韩高清一区二区三区在线 | 亚洲精品在线国产| 天堂日韩电影| 精品国产三区在线| 国产探花在线精品一区二区| 国产视频一区欧美| 日韩在线中文| 美女性感视频久久| 四虎在线精品| 蜜桃av一区| 婷婷色综合网| 日本精品在线中文字幕| 国产成人调教视频在线观看| 欧美日韩va| 伊人久久成人| 国产高清不卡| 久久精品九色| 欧美精品aa| 欧美亚洲三级|