0、前言
??作為一名前端開發(fā)者,在做表單驗(yàn)證或者寫一些gulp任務(wù)或webpack配置時(shí)都不可避免的會(huì)用到正則料皇,雖然零零散散看過一些正則相關(guān)語法啥辨,但始終覺得沒吃透涡匀,直到遇到這篇文章(強(qiáng)烈推薦)。本文僅記錄個(gè)人覺得很有價(jià)值的幾個(gè)點(diǎn)溉知。
1陨瘩、正則語法
正則是匹配模式,要么匹配字符级乍,要么匹配位置舌劳。
對(duì)于一個(gè)字符串string='hello',你應(yīng)該這樣看待它:
也就是要看成字符和位置的集合玫荣,而不是單單的是字符甚淡。
字符組
范圍表示法:[a-z]從a到z的所有小寫字母;
排除字符組:[^a-z]除a-z以外的所有字符捅厂;
常見縮寫:\d贯卦,\D,\w焙贷,\W撵割,\s,\S辙芍,.啡彬,其中'.'匹配任意非換行符、回車符故硅、行分隔符和段分隔符外遇。
此外,若要匹配任意字符契吉,可用:[\d\D]跳仿、[\w\W]、[\s\S]和[^]中任何的一個(gè)捐晶。-
多選分支
(p1|p2|p3)菲语,其中p1妄辩、p2和p3是子模式,用|(管道符)分隔山上,表示其中任何之一
注意:分支結(jié)構(gòu)是惰性的眼耀,當(dāng)?shù)谝粋€(gè)子模式匹配成功后,后面的模式會(huì)被忽略
-
位置匹配符(6個(gè))
^ $ \b \B (?=p) (?!p)
^:開始的位置佩憾;
$:結(jié)束的位置哮伟;
\b:單詞邊界,具體就是\w和\W之間的位置妄帘,也包括\w和^之間的位置楞黄,也包括\w和$之間的位置;
\B:\b的取反抡驼;
(?=p):p之前的位置鬼廓,正向先行斷言;
(致盟?!p):上述取反碎税,反向先行斷言;
把位置理解空字符馏锡,是對(duì)位置非常有效的理解方式雷蹂。同一個(gè)位置可以有多個(gè)空字符,就像^和首字母之間還可以有其它空位置一樣 -
括號(hào)的作用
1杯道、分組和分支/(ab)+/ //分組 /^I love (JavaScript|Regular Expression)$/ //分支
2匪煌、分組引用
主要是方便獲取小括號(hào)匹配到的內(nèi)容//1、match方法蕉饼,有小括號(hào)時(shí)虐杯,返回的數(shù)組中包含小括號(hào)匹配的內(nèi)容 var regex = /(\d{4})-(\d{2})-(\d{2})/; var string = "2017-06-12"; console.log( string.match(regex) ); // => ["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12"] //2、API引用法昧港,使用replace時(shí)可直接用$1等獲取小括號(hào)內(nèi)容 var regex = /(\d{4})-(\d{2})-(\d{2})/; var string = "2017-06-12"; regex.test(string); // 正則操作即可擎椰,例如 //regex.exec(string); //string.match(regex); console.log(RegExp.$1); // "2017" console.log(RegExp.$2); // "06" console.log(RegExp.$3); // "12" //3、反向引用 \1,\2 var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/; var string1 = "2017-06-12"; var string2 = "2017/06/12"; var string3 = "2017.06.12"; var string4 = "2016-06/12"; console.log( regex.test(string1) ); // true console.log( regex.test(string2) ); // true console.log( regex.test(string3) ); // true console.log( regex.test(string4) ); // false
3创肥、非捕獲分組
非捕獲分組的意義在于不引用括號(hào)的內(nèi)容达舒,節(jié)省內(nèi)存var regex = /(?:ab)+/g; var string = "ababa abbb ababab"; console.log( string.match(regex) ); //=>RegExp.$1值為'''',不用非捕獲模式時(shí)為"ab"
-
符號(hào)的優(yōu)先級(jí)
一個(gè)正則表達(dá)式涉及的操作符有:1.轉(zhuǎn)義符 \
2.括號(hào)和方括號(hào) (...)叹侄、(?:...)巩搏、(?=...)、(?!...)趾代、[...]
3.量詞限定符 {m}贯底、{m,n}、{m,}撒强、?禽捆、*笙什、+
4.位置和序列 ^ 、$胚想、 \元字符琐凭、 一般字符- 管道符(豎杠)|.
上面操作符的優(yōu)先級(jí)從上至下,由高到低浊服。
2统屈、寫好正則的建議
- 使用具體型字符組來代替通配符,來消除回溯
少用通配符'.'牙躺,減少回溯次數(shù)愁憔,提升匹配速度 - 使用非捕獲型分組(?:)
當(dāng)必須要用括號(hào),又不想引用時(shí)述呐,使用非捕獲型分組可節(jié)省內(nèi)存 - 獨(dú)立出確定字符
例如/a+/惩淳,可以修改成/aa*/蕉毯。后者能比前者多確定了字符a乓搬,可加快判斷是否匹配失敗,進(jìn)而加快移位的速度 - 提取分支公共部分
比如/abc|def/代虾,修改成/^(?:abc|def)/进肯。這樣做,可以減少匹配過程中可消除的重復(fù)棉磨。 - 減少分支的數(shù)量江掩,縮小它們的范圍
/red|read/,可以修改成/rea?d/乘瓤。此時(shí)分支和量詞產(chǎn)生的回溯的成本是不一樣的环形。
3、正則相關(guān)JS函數(shù)
String類型四個(gè)+RegExp類型二個(gè)衙傀,常用的是3+1
-
match
當(dāng)全局匹配時(shí)抬吟,match返回所有匹配結(jié)果,數(shù)組形式统抬;
當(dāng)局部匹配時(shí)火本,match返回一個(gè)結(jié)果和其它信息,如index,input,數(shù)組形式聪建;
當(dāng)沒有匹配到數(shù)據(jù)時(shí)钙畔,返回nullvar string = "2017.06.27"; var regex1 = /\b(\d+)\b/; var regex2 = /\b(\d+)\b/g; console.log( string.match(regex1) ); console.log( string.match(regex2) ); // => ["2017", "2017", index: 0, input: "2017.06.27"] // => ["2017", "06", "27"]
split
1、接受第二個(gè)參數(shù)金麸,表示分割后數(shù)組的長(zhǎng)度擎析;
2、和match一樣挥下,當(dāng)?shù)谝粋€(gè)參數(shù)是字符串時(shí)會(huì)將其轉(zhuǎn)為正則表達(dá)式揍魂,因此建議不要傳字符串挪鹏,而是直接傳正則replace
1、第二個(gè)參數(shù)可以是字符串或者函數(shù)愉烙,當(dāng)是函數(shù)時(shí)讨盒,第一個(gè)參數(shù)表示整個(gè)匹配的內(nèi)容,然后依次是括號(hào)匹配的內(nèi)容步责,再然后是index和input返顺;
2、str.replace返回的是新字符串蔓肯,str本身并未被改變遂鹊,即replace是不改變?cè)甲址摹?/p>-
test
/\d+/.test(123);//true
4、總結(jié)
本文是結(jié)合自身情況對(duì)老姚的這篇文章進(jìn)行的總結(jié)蔗包。收獲如下:
- 操作符優(yōu)先級(jí):轉(zhuǎn)義>括號(hào)>量詞>普通字符>管道符
- 正則表達(dá)式不光匹配字符秉扑,還匹配位置
- 位置符:^ $ (?=b) (?!b) \b \B,其中\(zhòng)b是\w與\W之間的位置调限,(?=b)是b之前的位置
- ^與首字母之間還可以有位置舟陆,尾字母和$同理。即同一個(gè)位置可以有多個(gè)空白字符耻矮。
- 寫好正則的建議 -第二節(jié)
5秦躯、案例
- 把"12345678",變成"12,345,678"
var string1 = "12345678",
string2 = "123456789";
reg = /(?!^)(?=(\d{3})+$)/g;
var result = string1.replace(reg, ',')
console.log(result);
// => "12,345,678"
result = string2.replace(reg, ',');
console.log(result);
// => "123,456,789"
(?!^) 表示非開頭的位置
(?=(\d{3})+$) 表示從結(jié)尾的位置開始往前連續(xù)三個(gè)數(shù)字之前的位置