成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

讀懂那些火星(正則)表達(dá)式:捕獲元與非捕獲元

Dr_Noooo / 1290人閱讀

摘要:先看一張來自于菜鳥教程的定義四種形式,加和不加有什么區(qū)別,區(qū)別就是捕獲元與非捕獲元,表現(xiàn)形式就是用方法去匹配,捕獲組會單純保存在一組變量中。捕獲元與非捕獲元搞懂了,那與啥區(qū)別呢,答案,兩個(gè)區(qū)別。

想讀懂世間所有的那些{{BANNED}}正則表達(dá)式?做夢,年紀(jì)輕輕,想啥呢,盡自己最大努力學(xué)就行

引子

JS學(xué)了用了也快一兩年了,對象啥的找到了也會用了,繼承啥的也入門了,但看別人的框架代碼,總是會隨時(shí)卡殼,有一個(gè)重大的原因,就是那看不懂的一串串火星文字(正則表達(dá)式),學(xué)習(xí)嗎,就是查缺補(bǔ)漏,不怕你不懂,就怕你覺得自己全懂了。說正事之前,先推薦一款軟件:RegexBuddy,無論是做正則的測試還是過程的研究,都是一款利器。

知識匯總

語法復(fù)習(xí),重點(diǎn)三塊知識:

貪婪匹配(? 0==1,* any)與那些相關(guān)的限定符({n},{n,m});

特殊字符:^ $ . * + ? = ! : | / ( ) [ ] { }
,火星文,基本就是他們組成的,要想匹配字符的本意,字面量表達(dá)式在特殊字符前加單斜杠,用new聲明的需要加雙斜杠;

非捕獲元字符:?:,?=(正向預(yù)查),?!(負(fù)向預(yù)查);

回溯引用,前面的字符匹配基本都和他有關(guān);

其他,什么字符邊界啊,括號啊,中括號啊,等等 ;

正則表達(dá)式解析原理:這個(gè)不算我等渣暫時(shí)能寫出來的,推薦一篇

層層遞進(jìn)剖析 貪婪匹配

先理解貪婪匹配,正則表達(dá)式的日常應(yīng)用基本也就滿足了,在菜鳥教程的語法開篇就已經(jīng)提的很詳細(xì)了,比如有一個(gè)regex:/Chapter[1-9]/,這個(gè)字符串我們只能匹配到Chapter1-Chapter9,也就是Chapter的一級標(biāo)題,但我們想匹配到二級或者三級標(biāo)題怎么辦,這里就用到了貪婪匹配,就是在目標(biāo)字符串中最大化的匹配結(jié)果,將前面的regex:/Chapter[1-9]/改成/Chapter[1-9]+/,這樣我們就能匹配Chapter1,Chapter12,Chapter123,但如果我們將其改為/Chapter[1-9]?/,這個(gè)無論/Chapter后面輸入多少個(gè)數(shù)字,都只能最多匹配一個(gè)數(shù)字,這里就是Chapter1,但與最初的表達(dá)式不同的是,這個(gè)表達(dá)式也能匹配裸的Chapter,這就是所謂(X?),問號前面的X可出現(xiàn)0次或者1次,當(dāng)我們將其改為/Chapter[1-9]星號(避開markdown語法)/,這個(gè)最后可以達(dá)到?和+共同的結(jié)果,也就是所謂的,x出現(xiàn)任意次數(shù)。上面這些我們也可以通過[n,m]即n= 懶惰匹配

與貪婪匹配成對的另一個(gè)叫懶惰匹配,在前面出現(xiàn)的所有貪婪匹配后面加上一個(gè)?,這樣整個(gè)表達(dá)式就成了懶惰匹配,可以理解為最小化匹配,比如/Chapter[1-9]+/匹配Chapter12345的結(jié)果是Chapter12345,但/Chapter[1-9]+?/匹配的結(jié)果就是Chapter1;/Chapter[1-9]{2,4}/匹配結(jié)過是Chapter1234,而/Chapter[1-9]{2,4}?/結(jié)過是Chapter1234,這就是所謂的最小化去匹配結(jié)果,取下限,通常稱為懶惰模式。

捕獲元與非捕獲元

以前看到什么?:,?=,?!,用的少,也就沒留意,最近大面積災(zāi)荒,經(jīng)??吹剑跏强謶?,以至于前面在讀gulp里面碰見個(gè)regex表達(dá)式:/-[0-9a-f]{8,10}-?/(匹配app-7ef5d9ee29.css這一類表達(dá)式中的md5值),就一頭栽進(jìn)去,"-?"到底又有什么特殊的含義,最后才發(fā)現(xiàn),那TMD就是一個(gè)貪婪匹配,你個(gè)蠢貨,但確實(shí)搞不懂源碼作者在想啥,也許是我沒碰到app-7ef5d9ee29-any.css這樣的文件名,要不非得多加個(gè)"-?"干啥,讓我直往坑里跳。
回到正題,先搞懂什么叫捕獲組,概括起來就是,用括號如‘(pattern)’這樣的形式,匹配滿足括號中的,就是一個(gè)捕獲組。先看一張來自于菜鳥教程的定義:
四種形式,加?和不加有什么區(qū)別,區(qū)別就是捕獲元與非捕獲元,表現(xiàn)形式就是用exec方法去匹配,捕獲組會單純保存在一組變量中。理論太枯燥,直接看例子,來源于JS高設(shè)page106,略有改動(dòng):

    var str ="mom and dad and baby";
    var pattern = /mom( and dad( and baby))/; //捕獲元形式
    var pat= /mom(?: and dad(?: and baby))/; //非捕獲元形式
    var mat = pattern.exec(str);
    var match = pat.exec(str);
    console.log(mat);
    console.log(match);


看著devtools打印的結(jié)果,是不是有點(diǎn)眉目,是的,匹配的結(jié)果雖一致,但捕獲組匹配時(shí),將滿足捕獲元形式的單元多帶帶保存為一個(gè)匹配結(jié)果,而非捕獲元不多帶帶保存,只保存完整匹配結(jié)果。我們常見的Regexp.$1,$2其實(shí)就是對捕獲組結(jié)果的引用。
捕獲元與非捕獲元搞懂了,那(?:pattern)與(?=pattern)啥區(qū)別呢,答案,兩個(gè)區(qū)別。區(qū)別一:前者匹配的結(jié)果包含捕獲元,后者匹配的結(jié)果則不包含;區(qū)別二:前者匹配捕獲元時(shí),消耗字符(索引),而后者不消耗。還是來看一個(gè)例子:

var str ="ababa";
var pattern = /ab(?:a)/g;
var pat=  /ab(?=a)/g; 
var mat = pattern.exec(str);
var match = pat.exec(str);
console.log(mat);
console.log(match);       
 mat = pattern.exec(str); //全局模式,第二次匹配
 match = pat.exec(str); //全局模式,第二次匹配
console.log(mat);
console.log(match); 

從上面代碼運(yùn)行的截圖可以看出區(qū)別一,也就是(?:pattern)的形式的捕獲元匹配的結(jié)果會保存在最終的結(jié)果中,而(?=pattern);區(qū)別二看的不是很明顯,這時(shí)我們需要依靠RegexBuddy,這個(gè)過程中到底發(fā)生了什么?看運(yùn)行截圖,如果你夠仔細(xì),你可以發(fā)現(xiàn)區(qū)別,第一次匹配到結(jié)果,開始第二次匹配時(shí),?:是從字符索引3開始,而?=是從2開始,這就是前面所說的消耗字符與不消耗字符。

好了,最后一個(gè)問題,整箱預(yù)查(?=pattern)與負(fù)向預(yù)查(?!pattern),其實(shí)從中文單純來理解負(fù)向預(yù)查,是會帶來歧義的。這里的負(fù)向其實(shí)單單就是正向預(yù)查的取反,即要匹配的字符不滿足捕獲的條件,才能匹配到結(jié)果。
如果文章有什么描述不正確或模糊的地方,還請及時(shí)指正。
好了,先就說這么多嘛,雖然是無業(yè)游民,那也應(yīng)該有享受周末的權(quán)利吧,畢竟找工作的壓力那么大,還是要自我緩解一下,see you last week。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84674.html

相關(guān)文章

  • 看懂火星文(三) 2019.4.3更新

    摘要:則是將作為一組,表示出現(xiàn)多次。如果沒有使用標(biāo)示,則僅返回第一個(gè)完整匹配及其相關(guān)的捕獲組。構(gòu)造函數(shù)的全局屬性到存儲了分組匹配的結(jié)果。 showImg(https://segmentfault.com/img/remote/1460000018749261?w=1362&h=781); 感謝 本文參考《正則表達(dá)式迷你書》 分組和分支結(jié)構(gòu) 分組 括號可以提供分組的功能。/a+/, 標(biāo)示a出現(xiàn)...

    Charlie_Jade 評論0 收藏0
  • Python正則達(dá)式很難?一篇文章搞定他,不是我吹!

    摘要:正則表達(dá)式語法字符與字符類特殊字符以上特殊字符要想使用字面值,必須使用進(jìn)行轉(zhuǎn)義字符類包含在中的一個(gè)或者多個(gè)字符被稱為字符類,字符類在匹配時(shí)如果沒有指定量詞則只會匹配其中的一個(gè)。 1. 正則表達(dá)式語法 1.1 字符與字符類 1 特殊字符:.^$?+*{}| 以上特殊字符要想使用字面值,必須使用進(jìn)行轉(zhuǎn)義 2 字符類 1. 包含在[]中的一個(gè)或者多個(gè)字符被稱為字符類,字符類在匹配時(shí)如果沒有指...

    dcr309duan 評論0 收藏0
  • 【JS基礎(chǔ)】正則達(dá)式入門

    摘要:對于含有量詞正則表達(dá)式,量詞是貪婪模式,會優(yōu)先選擇盡可能多的匹配修飾的字符,所以該表達(dá)式會優(yōu)先選擇匹配一個(gè)字符,當(dāng)匹配不到時(shí)再選擇不匹配字符。 正則表達(dá)式的語法 普通字符 字母、數(shù)字、漢字、下劃線以及一些沒有特殊定義的標(biāo)點(diǎn)符號,都屬于普通字符,正則表達(dá)式中的普通字符匹配字符本身,如: var str = abced console.log(str.match(/a/)) // [a,...

    Mr_houzi 評論0 收藏0
  • 正則達(dá)式前端使用手冊

    摘要:非貪婪模式盡可能少的匹配所搜索的字符串,而默認(rèn)的貪婪模式則盡可能多的匹配所搜索的字符串。 導(dǎo)讀 你有沒有在搜索文本的時(shí)候絞盡腦汁, 試了一個(gè)又一個(gè)表達(dá)式, 還是不行. 你有沒有在表單驗(yàn)證的時(shí)候, 只是做做樣子(只要不為空就好), 然后燒香拜佛, 虔誠祈禱, 千萬不要出錯(cuò). 你有沒有在使用sed 和 grep 命令的時(shí)候, 感覺莫名其妙, 明明應(yīng)該支持的元字符, 卻就是匹配不到. 甚至,...

    zhoutao 評論0 收藏0
  • 正則達(dá)式小記

    摘要:什么是正則表達(dá)式正則表達(dá)式是用于匹配字符串中字符組合的模式。在中,正則表達(dá)式也是對象。正則表達(dá)式存在于大部分的編程語言,就算是在寫時(shí)也會不經(jīng)意的用到正則。第二個(gè)參數(shù)卻是可以傳入一個(gè)字符串,也可以傳入一個(gè)回調(diào)函數(shù)。 什么是正則表達(dá)式 正則表達(dá)式是用于匹配字符串中字符組合的模式。在 JavaScript中,正則表達(dá)式也是對象。這些模式被用于 RegExp 的 exec 和 test 方法,...

    DevTTL 評論0 收藏0

發(fā)表評論

0條評論

Dr_Noooo

|高級講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<