正則的解釋
正則表達式的創(chuàng)建
// 兩個正斜杠定義正則字面量的邊界
var reg = /test/;
// 構(gòu)造RegExp實例
var reg = new RegExp("test");
3個匹配標志的使用方法
// i 表示不區(qū)分大小寫
// g 表示全局匹配,而不是只匹配第一次出現(xiàn)的結(jié)果
// m 表示允許多行匹配
var reg = /test/igm;
var reg = new RegExp("test","igm");
正則的術語與操作符
匹配一個有限字符集中的某一個字符
// 表示匹配a,b,c中的任意一個字符
var reg = /[abc]/;
在中括號第一個括號后面加入^申鱼,表示匹配該組有限字符集以外的字符
// 表示匹配除了a,b,c以外的任意字符
var reg = /[^abc]/;
在字符集之間加入-愤诱,表示制定一個范圍
// 表示匹配a到m之間的任意字符,包括a和m
var reg = /[a-m]/;
轉(zhuǎn)義捐友,在正則表達式中淫半,字母和數(shù)字都能代表自己本身,但類似$-.[]等特殊字符都有其他含義楚殿,要匹配這些字符撮慨,需要用\對其進行轉(zhuǎn)義
// 表示匹配$字符
var reg = /\$/;
匹配的開始與結(jié)束
當^作為正則表達式的第一個字符時竿痰,表示必須從字符串的開頭進行匹配脆粥。
// 表示匹配以abc開頭的字符串
var reg = /^abc/;
當$作為正則表達式的最后一個字符時,表示該模式必須出現(xiàn)在字符串的結(jié)尾影涉。
// 表示匹配以abc結(jié)尾的字符串
var reg = /abc$/;
同時使用^和$時变隔,表示匹配模式必須包含整個字符串,即匹配模式就是字符串本身蟹倾,沒有任何其他字符匣缘。
// 表示匹配"abc"這個字符串,"abcabc"之類的不會匹配
var reg = /^abc$/;
重復出現(xiàn)
在一個字符后面加一個?鲜棠,表示該字符是可選的肌厨,也就是可以出現(xiàn)一次或不出現(xiàn)
// 表示匹配abc或者bc,
var reg = /a?bc/;
在一個字符后面加一個+豁陆,表示該字符可以出現(xiàn)一次或多次
// 表示匹配abc或者aaabc柑爸,
var reg = /a+bc/;
在一個字符后面加一個*,表示該字符可以出現(xiàn)零次或多次盒音,即任意次數(shù)
// 表示匹配abc或者aaabc或者bc表鳍,
var reg = /a*bc/;
在字符后跟花括號,在起重指定一個數(shù)字祥诽,表示該字符出現(xiàn)的次數(shù)
// 表示匹配aaaa譬圣,
var reg = /a{4}/;
在字符后跟花括號,在起重指定一個區(qū)間雄坪,表示該字符出現(xiàn)的次數(shù)區(qū)間
// 表示匹配a出現(xiàn)次數(shù)在4到10之間任意次數(shù)的字符串厘熟,包括4次和10次
var reg = /a{4,10}/;
次數(shù)區(qū)間第二個數(shù)值是可選的维哈,當沒有第二個數(shù)字是绳姨,表示匹配一個開區(qū)間
// 表示匹配a出現(xiàn)次數(shù)至少4次
var reg = /a{4,}/;
以上重復操作符可以是貪婪的或者非貪婪的笨农,默認情況下是貪婪的就缆,表示盡可能多的匹配,例如谒亦,匹配"aaa"字符串時竭宰,/a+/模式將匹配所有3個a空郊。在操作符后面加上?,表示非貪婪模式切揭,將進行最小限度的匹配狞甚,匹配"aaa"字符串時,/a+?/模式只會匹配一個a字符廓旬。因為一個a字符就滿足+表示的一次或多次的情況哼审。
預定義字符類
\t 水平制表符
\b 空格
\n 換行符
. 匹配除換行以外的任意字符
\d 匹配任意數(shù)字,等價于[0-9]
\D 匹配任意非數(shù)字孕豹,等價于[^0-9]
\w 匹配包括下劃線的任意單詞字符涩盾,等價于[A-Za-z0-9_]
\W 匹配任何非單詞字符,等價于[^A-Za-z0-9_]
\s 匹配任何空白符励背,包括空格春霍,制表符,換頁符等
\S 匹配任何非空白字符
\b 匹配單詞邊界
\B 匹配非單詞邊界
分組
在為匹配模式加上小括號叶眉,可以讓其成為一個分組址儒,后續(xù)添加的操作符可以影響整個分組。
// 表示匹配出現(xiàn)一次或連續(xù)多次的ab字符串衅疙,例如"xxxabxxx"莲趣,"xxxabababxxx"
var reg = /(ab)+/;
或操作符
豎線|表示或操作符
// 表示匹配a或b
var reg = /a|b/;
// 表示匹配出現(xiàn)一次或多次的"ab"或"ba"
var reg = /(ab)+|(ba)+/;
反向引用
反斜杠后面加一個數(shù)字表示要引用之前已經(jīng)匹配到的分組
// \1表示再匹配一次第一個分組([ab])匹配到的內(nèi)容,\2表示再匹配一次第二個分組(a)匹配到的內(nèi)容饱溢。
// 并且不是再次對分組中的模式進行匹配喧伞,而是對已經(jīng)匹配到的一模一樣的內(nèi)容進行精確匹配。
// 例如第一個分組([ab])匹配到了字符b理朋,\1匹配的就也必須是字符b
var reg = /([ab])(a)\1\2/;
反向引用常用來匹配元素的標簽
// \1表示對第一個分組(\w+)匹配到的內(nèi)容再次匹配絮识,內(nèi)容必須完全相同。因為標簽的開始和關閉是相同的嗽上。
var reg =/<(\w+)>.*<\/\1>/;
var a = "<strong>some thing</strong>";
console.log(reg.test(a)); // true
正則表達式的編譯
正則表達式的編譯發(fā)生在第一次被創(chuàng)建的時候次舌,而執(zhí)行則是發(fā)生在我們使用編譯過的正則表達式進行字符串匹配的時候。所以正則表達式只應該編譯一次兽愤,并將其保存在一個變量中以供后續(xù)使用彼念,這是一個重要的優(yōu)化過程。每次創(chuàng)建的正則表達式都是一個新的對象浅萧,其結(jié)果都是獨一無二的逐沙。
使用構(gòu)造器(new RegExp())可以通過動態(tài)的字符串創(chuàng)建正則表達式。
捕獲匹配的片段
匹配到的內(nèi)容中洼畅,每一個括號分組都是一個片段吩案,使用字符串的match()方法可以捕獲匹配的片段。
在非全局匹配時帝簇。其返回結(jié)果是一個數(shù)組徘郭,第一個索引的值是該匹配的完整結(jié)果靠益,之后的參數(shù)是每一個捕獲的片段。
在全局匹配時残揉。其返回結(jié)果也是一個數(shù)組胧后,但數(shù)組的值是所有的匹配結(jié)果,每一個匹配結(jié)果的捕獲片段是不會返回的抱环。
// 非全局匹配
var reg =/<(\w+)([^>]*)>/;
var a = '<div class="abc">hello</div>';
var b = a.match(reg);
console.log(b); // ["<div class="abc">", "div", " class="abc""]
// 全局匹配
var reg =/(\w+)([^>]*)>/g;
var a = '<div class="abc">hello</div>';
var b = a.match(reg);
console.log(b); // ["div class="abc">", "hello</div>"]
正則表達式的exec()方法壳快,可以對同一個字符串進行多次匹配,每一次匹配都會返回下一個匹配的結(jié)果
var reg =/<(\w+)([^>]*)>/g;
var a = '<div class="abc"><p>hello <span>world</span></p></div>';
var b = reg.exec(a);
var c = reg.exec(a);
var d = reg.exec(a);
console.log(b); // ["<div class="abc">"]
console.log(c); // ["<p>"]
console.log(d); // ["<span>"]
捕獲的引用
在replace()方法中镇草,可以使用$1眶痰,$2,$3這樣的語法來引用之前捕獲到的分組陶夜。
// 正則中的$1表示第一個捕獲到的分組中的內(nèi)容凛驮,即[A-Z]匹配到的內(nèi)容裆站。
var a = 'borderColor';
var b = a.replace(/([A-Z])/g,"-$1").toLowerCase();
console.log(b); // border-color
沒有捕獲的分組
在分組的左括號后加一個?:標記条辟,表示這個分組不需要被捕獲。
var reg = /(?:-[A-Z])/;
var a = 'border-Color';
var b = a.match(reg);
// 只返回了匹配的內(nèi)容宏胯,沒有返回分組中的內(nèi)容
console.log(b[1]); // undefined
在不需要捕獲的時候羽嫡,盡量可能的使用非捕獲分組,減少引擎的工作量肩袍。
利用函數(shù)進行替換
replece()方法的第二個參數(shù)可以傳入一個函數(shù)杭棵,全局模式下每個匹配都會調(diào)用這個函數(shù),該函數(shù)有一個參數(shù)列表氛赐,分別為:
- 匹配的完整文本
- 匹配的捕獲魂爪,一個捕獲對應一個參數(shù)
- 匹配字符在元字符串中的索引
- 源字符串
function up(all,str) {
return "-"+str.toLowerCase();
}
var a = 'borderBottomColor';
var b = a.replace(/([A-Z])/g,up);
console.log(b); // border-bottom-color
利用這一特性可以修改一些數(shù)據(jù)的格式,例如將"a=1&a=2&a=3&b=4&b=5"修改為"a=1,2,3&b=4,5"艰管。
function up(str) {
var keys = {}; // 保存數(shù)據(jù)
str.replace(/([^=&]+)=([^&]+)/g,function (all, key, value) {
keys[key]=keys[key]?keys[key]+","+value:value;
});
var result = [];
for (var key in keys){
result.push(key+"="+keys[key]);
}
return result.join("&");
}
var a = 'a=1&a=2&a=3&b=4&b=5';
console.log(up(a)); // a=1,2,3&b=4,5
常見問題
// 刪除前后空格滓侍,低端瀏覽器不支持trim()方法
var a = ' abc abc ';
console.log(a.replace(/^\s+|\s+$/g,"")); // abc abc
// 匹配換行符,/[\S\s]*/ 表示匹配所有字符
var a = 'abc\nabc';
console.log(/[\S\s]*/.exec(a)[0]);
// 匹配Unicode
var a = '\u5FCD\u8005\u30D1\u30EF\u30FC';
console.log(a.match(/[\w\u0080-\uFFFF_-]+/)[0]); // 忍者パワー