想閱讀世界上所有最好的正規表示式嗎? 做夢,年輕,你想要什麼,就盡力學習。
js已經學習和使用了差不多一兩年了,找到什麼東西就會用到物件,繼承一些東西就可以上手了,但是看看別人的框架**,總是隨時卡住,有乙個主要原因,那就是一串火星詞(正規表示式)看不懂,學習什麼,就是檢查和補空,不怕你不懂,怕你以為什麼都懂了。在開始做生意之前,讓我們推薦乙個軟體:regexbuddy,無論是進行定期測試還是過程研究,它都是乙個強大的工具。
語法複習,重點關注三條知識:貪婪匹配(?0==1, * any) 與那些相關的限定符 (,) 特殊字元: = ! / (
火星文字,基本上就是由它們組成的,為了配合漢字的原意,在特殊漢字之前加上字面意思,需要加上新的宣告; 非捕獲元字元:?:=(遠期預測), ?陰性預檢);回想起來,之前的人物匹配,基本上都和他有關; 其他,什麼字元邊界,括號,括號等; 正規表示式解析原理:這裡暫時還沒能寫出來,先推薦一篇了解貪婪匹配的文章,正規表示式的日常應用基本滿意,在菜鳥教程語法的開頭已經詳細提到過了,比如有乙個正規表示式:chapter[1-9], 這個字串我們只能匹配 chapter1-chapter9,也就是章節的一級標題,但是如果我們要匹配二級或者 **title 呢,這裡我們用貪婪匹配,就是最大化目標字串中的匹配結果,把之前的正規表示式:chapter[1-9] 改成 chapter[1-9],這樣我們就可以匹配 chapter1, 第 12 章和第 123 章。但是如果我們把它改成/chapter[1-9]?/
這是無論如何/chapter
由於輸入了多個數字,因此最多只能匹配乙個數字,即 chapter1,但與原始表示式不同的是,此表示式也可以匹配裸章節,稱為 (x?)。 ),問號前面的 x 可以出現 0 次或 1 次,當我們將其更改為/chapter[1-9]
星號(避免 markdown 語法),這可以在最後到達嗎? 常見的結果,也稱為,發生任意次數。 我們也可以通過 [n,m] 使用上面的內容,即 n=另乙個與貪婪匹配配對的稱為惰性匹配,所有前面出現的貪婪匹配後面都跟著乙個? ,使整個表示式變成乙個惰性匹配,可以理解為最小化匹配,例如 chapter[1-9] 匹配 chapter12345,結果是 chapter12345,但 chapter[1-9] ? 比賽結果是chapter1; 第[1-9]章是第1234章,第[1-9]章? 結是第1234章,稱為最小化取消匹配結果並採取下限,通常稱為懶惰模式。
你之前看到了什麼? :,=,?!用得少的時候沒注意,最近經常在大範圍內看到它,嚇得之前在讀吞口時遇到過乙個正規表示式:-[0-9a-f]-?(匹配 app-7ef5d9ee29。css expressions),一頭扎進去,'-?'到底有什麼特別的意思,最後我才發現,那是貪婪的匹配,你是個傻子,但是我真的不明白原始碼作者在想什麼,可能我沒有遇到app-7ef5d9ee29-any。CSS的'-?'你在幹嘛,讓我直接跳進坑里。
回到正題,我們先來了解一下什麼是捕獲組,可以用括號的形式概括為'(pattern)',匹配滿足括號。 讓我們看一下 rookie 教程中的乙個定義:
四種形式,加上? 捕獲元素和非捕獲元素有什麼區別,表現就是用exec方法進行匹配,將捕獲組簡單地儲存在一組變數中。 理論太無聊了,看看例子就知道了,**在js中設定了page106高,略有改動:
var str ='mom and dad and baby';var pattern = /mom( and dad( and baby))/;捕獲元形式 var pat= mom(?:and dad(?:and baby))/;非捕獲元形式 var mat = patternexec(str);var match = pat.exec(str);console.log(mat);console.log(match);
看著devtools列印的結果,是不是有點讓人瞠目結舌,是啊,雖然匹配結果一致,但是當捕獲組匹配時,符合捕獲元形式的單位會單獨儲存為匹配結果,非捕獲元素不會單獨儲存,只儲存完整的匹配結果。 我們共同的正規表示式$1、$2 實際上是對捕獲組結果的引用。
捕獲元素和非捕獲元素已經弄清楚了,即(?:p attern) 和 (?=模式)有什麼區別,答案,兩個區別。區別 1:前者匹配的結果包含捕獲元素,而後者的結果則不包含捕獲元素。 區別 2:當前者與捕獲元匹配時,它消耗字元(索引),而後者則不。 讓我們看乙個例子:
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 = patexec(str);全域性模式,第二個比賽控制台log(mat);console.log(match);
從上面**執行的截圖中,可以看出區別之一,那就是(?:p attern) 儲存在最終結果中,而 (?=pattern);區別不是很明顯,我們需要依靠正規表示式好友,在這個過程中到底發生了什麼? 看看執行的截圖,如果你足夠細心的話,你就能發現其中的區別,第一次匹配到結果,第二次開始匹配,?: 來自字元索引 3 和 ? = 來自 2,這就是我們之前所說的關於使用字元與不使用字元的內容。
好吧,最後乙個問題,FCL預檢(?=pattern) 和負預檢查 (?!模式),事實上,僅從中文來理解否定預審會帶來歧義。這裡的負方向其實只是對正預檢的否定,即為了匹配結果而對待匹配的字元不滿足捕獲條件。