淺談?wù)齽t速記法的技巧
給你一篇文章,如何挑選出你想要的字符串呢?你可以從左到右從上到下,一個(gè)一個(gè)字符讀取出來(lái),寫(xiě)一大堆if做判斷。這樣太麻煩了,正則就是將以上過(guò)程抽象出來(lái),用一些特定符號(hào)就能表示出大部分規(guī)則
對(duì)大部分人來(lái)說(shuō),正則主要是難記,其實(shí)只要對(duì)正則符號(hào)分類記憶,就會(huì)發(fā)現(xiàn)核心概念其實(shí)特別簡(jiǎn)單
注:本文會(huì)假設(shè)你至少看過(guò)一遍正則的文檔,如果沒(méi)看過(guò),可以看mdn(有中文翻譯),如果覺(jué)得mdn排版亂,推薦去https://devdocs.io/javascript/global_objects/regexp學(xué)習(xí)。本文所使用語(yǔ)言為javascript
元字符
/a/
中的a就是一個(gè)元字符,一個(gè)元字符匹配一個(gè)實(shí)體字符,這里的“a”沒(méi)有特殊含義,就匹配一個(gè)英文a
像/\d/
就匹配0到9的所有數(shù)字,如果兩個(gè)連寫(xiě)/\d\d/
就可以匹配10到99的所有數(shù)字
/./
可以匹配任何字符
集合
假如有一串字符串'0123456789'
,我只想匹配其中的'3','6','9',這時(shí)可以放在集合中/[369]/
執(zhí)行后會(huì)發(fā)現(xiàn)只有3被匹配到,是因?yàn)榧现胁还軐?xiě)多少東西都代表一個(gè)元字符,集合也是一種元字符
你可能見(jiàn)過(guò)這樣都集合/[0-9a-zA-Z_]/
它代表匹配所有數(shù)字,字母和下劃線,它與元字符/\w/的效果是一樣的,集合更靈活\w更方便
排除型集合
/[^0-9]/
除了數(shù)字都匹配(我喜歡叫它否定集合)
或(多選)
假設(shè)我有一大堆書(shū)單,我希望從中匹配出naroto和one piece,那么可以這樣寫(xiě)/naroto|one pice/
豎線代表或,a或b,你也可以寫(xiě)多個(gè)a|b|c|d,你當(dāng)然可以寫(xiě)出0|1|2...|9來(lái)匹配所有數(shù)字。但要注意和集合的區(qū)別,集合是一個(gè)元字符,不能匹配單詞,|
兩邊可以是多個(gè)元字符
分組
我現(xiàn)在有一堆文件,我希望匹配出后綴是.css和.less的文件,你可以很自然的寫(xiě)出/.css|.less/
這樣的代碼。其實(shí)還有一個(gè)簡(jiǎn)便寫(xiě)法/.(c|le)ss/
,分組可以將若干個(gè)元字符放在同一個(gè)作用域中做處理,通過(guò)分組我們可以寫(xiě)出更簡(jiǎn)練的代碼
分組還有一個(gè)特殊的用法,思考如何匹配'asd_asd_asd_asd_asd'
這種字符串?
答案是/(asd)(_\1)+/,\1
是個(gè)非常特殊的元字符,代表重復(fù)使用第一個(gè)分組的匹配結(jié)果,\2就代表第二個(gè),以此類推,+加號(hào)表示重復(fù)一到多次(這個(gè)后面會(huì)講),需要注意的是計(jì)數(shù)從1開(kāi)始,\0代表另外的意思(請(qǐng)看文檔)
量詞
一長(zhǎng)串字符中我只想匹配連續(xù)的數(shù)字,但/\d/
只會(huì)匹配一個(gè),這時(shí)候可以使用量詞/\d{n,}/
,n寫(xiě)幾就是幾到多,比如{1,}就是1到多。{n}這種寫(xiě)法表示n個(gè)相連,匹配2333可以寫(xiě)成/23{3}/
還有幾個(gè)簡(jiǎn)寫(xiě)的量詞
- +代表1到多,等于{1,}
- *代表0到多,等于{0,}
- ?代表0或1個(gè),等于{0,1}
貪婪模式和非貪婪模式
量詞有個(gè)尷尬的地方,比如用/.*a/
去匹配 '123a123a'
,本來(lái)希望得到'123a'
,實(shí)際卻得到'123a123a'
。這是因?yàn)槿魏巫址紳M足/./
加上量詞會(huì)導(dǎo)致從頭匹配到尾,但因?yàn)槲覀冞€有其他元字符,所以這時(shí)正則引擎會(huì)回溯,將已經(jīng)匹配的結(jié)果從后往前一個(gè)個(gè)拿出來(lái),與剩下的元字符相匹配。
這種模式叫貪婪模式,它可能會(huì)產(chǎn)生預(yù)期之外的結(jié)果和不必要的性能浪費(fèi)
解決方案是使用非貪婪模式,在量詞后面加?
問(wèn)號(hào)可以得到最小結(jié)果,現(xiàn)在使用/.*?a/
去匹配就可以得到'123a'
了。任何量詞后都可以使用非貪婪模式
環(huán)視
x(?=y)
這個(gè)功能有很多種翻譯,比如零寬斷言,我個(gè)人感覺(jué)比較準(zhǔn)確的是“正向肯定環(huán)視”
x(?!y)
正向否定環(huán)視
x代表元字符,y也代表元字符,x(?=y)
的意思是緊接著y的x,比如 '-1a--2b-'
,使用/\d(?=a)/
去匹配,會(huì)得到1;/\d(?!a)/去匹配,會(huì)得到2。
這功能怎么用?舉個(gè)例子,有一段字符串'a(123)b'
,我只想要括號(hào)內(nèi)的內(nèi)容,但不想要括號(hào)
我需要匹配到右括號(hào)左邊的位置,那么我可以寫(xiě)成/(?=\))/
(注意括號(hào)需要轉(zhuǎn)義),我不想要左括號(hào)/[^(]/
,我不關(guān)心括號(hào)內(nèi)的內(nèi)容/.*/
,這時(shí)組合三個(gè)正則就變成了/[^(].*(?=\))/
實(shí)際上這個(gè)功能匹配的是位置,從匹配到的位置開(kāi)始找元字符,所以你如果在環(huán)視后面加量詞是沒(méi)用的
其他
^
和$
也是匹配位置的元字符,分別是匹配開(kāi)頭和結(jié)尾,比如我們想匹配文件結(jié)尾是.js的文件可以寫(xiě)成/.js$/
。匹配http開(kāi)頭的鏈接可以寫(xiě)成/^http:\/\//
還有一些特殊的\u[\b]\0等,需要你自己看文檔
標(biāo)識(shí)符
g:一個(gè)正則只會(huì)匹配一次,如果加上g標(biāo)識(shí)符就會(huì)全局匹配, /\d/g
,這個(gè)正則是不管兩個(gè)數(shù)字之間隔了什么,都會(huì)將所有數(shù)字匹配出來(lái)
i:不區(qū)分大小寫(xiě)/^http:\/\//i
就會(huì)匹配http://和HTTP://
核心概念就這么多,其他內(nèi)容請(qǐng)?jiān)敿?xì)查看文檔
你以為這就結(jié)束了?其實(shí)還有后續(xù)噠!
我要繼續(xù)說(shuō)環(huán)視
還有個(gè)神奇的逆向環(huán)視沒(méi)有講x(?<=y)
,因?yàn)檫@是18年才進(jìn)正式標(biāo)準(zhǔn)的功能,雖然它可能比js年齡大,但js就是不支持你怕不怕!
前面那個(gè)/[^(].*(?=\))/
可以改成/(?<=y).*(?=\))/
正則最大但坑就是,讓新手產(chǎn)生正則無(wú)所不能的想法,一個(gè)復(fù)雜字符串處理總以為可以通過(guò)一個(gè)神奇的正則來(lái)搞定。
正則不是萬(wàn)能的!
還是之前的例子,給字符串'a(1\(2(3)'
讓你取括號(hào)內(nèi)的內(nèi)容請(qǐng)問(wèn)你怎么???首先應(yīng)該弄清需求,如果正則過(guò)于難寫(xiě),可以用js的字符串處理函數(shù)輔助正則,分部操作。另外正則的性能并不高,不是說(shuō)很復(fù)雜的操作寫(xiě)成一行正則性能就比其他方式快了,沒(méi)有測(cè)試就沒(méi)有發(fā)言權(quán)
正則理論上是有極限的,舉個(gè)例子,有字符串1xxxyyyy2
讓你取{n}個(gè)x和{m}個(gè)y,n和m是不確定個(gè)數(shù),寫(xiě)成x{1,}y{1,}
是沒(méi)問(wèn)題的,但如果要求是x{n}y{n}
就不行了,比如一個(gè)字符串有3個(gè)x,你就要取3個(gè)y,有4個(gè)x,你就要取4個(gè)y,單靠正則就無(wú)法完成了。
正則難,難在門檻高,門檻高在難記,之所以難記,其實(shí)還是因?yàn)榉慈祟惖姆?hào)讓你下意識(shí)的排斥它。熟悉正則,正式正則,學(xué)會(huì)正則,會(huì)給你帶來(lái)超乎想象的便利!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:使用正則表達(dá)式實(shí)現(xiàn)網(wǎng)頁(yè)爬蟲(chóng)的思路詳解
欄 目:正則表達(dá)式
本文標(biāo)題:淺談?wù)齽t速記法的技巧
本文地址:http://mengdiqiu.com.cn/a1/zhengzebiaodashi/11193.html
您可能感興趣的文章
- 01-11正則表達(dá)式實(shí)現(xiàn)添加、刪除、替換三種功能
- 01-11python 用正則表達(dá)式篩選文本信息的實(shí)例
- 01-11正則表達(dá)式之匹配數(shù)字范圍
- 01-11python爬蟲(chóng)正則表達(dá)式之處理?yè)Q行符
- 01-11正則表達(dá)式匹配路由的實(shí)現(xiàn)代碼
- 01-11正則表達(dá)式截取身份證號(hào)碼加密的方法
- 01-11js正則表達(dá)式 匹配兩個(gè)特定字符間的內(nèi)容示例
- 01-11MySQL使用正則表達(dá)式進(jìn)行查詢操作經(jīng)典實(shí)例總結(jié)
- 01-11python正則表達(dá)式之對(duì)號(hào)入座篇
- 01-11詳解正則表達(dá)式實(shí)現(xiàn)二代身份證號(hào)碼驗(yàn)證


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-11正則表達(dá)式實(shí)現(xiàn)添加、刪除、替換三
- 01-11正則表達(dá)式之匹配數(shù)字范圍
- 01-11python 用正則表達(dá)式篩選文本信息的實(shí)
- 01-11正則表達(dá)式匹配路由的實(shí)現(xiàn)代碼
- 01-11python爬蟲(chóng)正則表達(dá)式之處理?yè)Q行符
- 01-11js正則表達(dá)式 匹配兩個(gè)特定字符間的
- 01-11正則表達(dá)式截取身份證號(hào)碼加密的方
- 01-11python正則表達(dá)式之對(duì)號(hào)入座篇
- 01-11MySQL使用正則表達(dá)式進(jìn)行查詢操作經(jīng)典
- 01-11詳解正則表達(dá)式實(shí)現(xiàn)二代身份證號(hào)碼
隨機(jī)閱讀
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10C#中split用法實(shí)例總結(jié)