正則表達(dá)式(Regular Expression)是計(jì)算機(jī)科學(xué)的一個(gè)概念收津。正則表達(dá)式使用單個(gè)字符串來描述、匹配一系列符合某個(gè)句法規(guī)則的字符串
一喜命、JS創(chuàng)建正則表達(dá)式
1. 創(chuàng)建方式
- 字面量創(chuàng)建
var reg = /正則表達(dá)式主體/修飾符(可選)
- 構(gòu)造函數(shù)創(chuàng)建
var reg = new RegExp('\s', 'ig')
注意:構(gòu)造函數(shù)創(chuàng)建方式第一個(gè)參數(shù)可以使用變量己儒,因此如果想使用字符串變量來創(chuàng)建正則,只能使用構(gòu)造函數(shù)創(chuàng)建法
2. 修飾符
- g:global树埠,全文搜索可帽,不添加的話搜索到第一個(gè)結(jié)果停止搜索
- i:ingore case擦盾,忽略大小寫窒舟,默認(rèn)大小寫敏感
- m:multiple lines系忙,多行搜索
var str = "abcggab\nabcpab"; var reg1 = /^abc/g; console.log(str.match(reg1)); //['abc'] var reg2 = /^abc/gm; //使用多行搜索 console.log(str.match(reg2)); //['abc', 'abc']
二、JS正則表達(dá)式常用方法
1. 正則對象實(shí)例的屬性
-
source
:正則表達(dá)式的源字符串 -
global
:是否全局搜索辜纲,默認(rèn)是false -
ignoreCase
:是否大小寫敏感笨觅,默認(rèn)是false -
multiline
:多行搜索,默認(rèn)值是false -
lastIndex
:是當(dāng)前表達(dá)式模式首次匹配內(nèi)容中最后一個(gè)字符的下一個(gè)位置耕腾,每次正則表達(dá)式成功匹配時(shí),lastIndex
屬性值都會(huì)隨之改變
2. 正則對象實(shí)例的方法
RegExp.prototype.test(str)
測試字符串中是否存在正則表達(dá)式模式杀糯,如果存在則返回true
扫俺,否則返回false
RegExp.prototype.exec(str)
將正則表達(dá)式模式在字符串中運(yùn)行查找,如果exec()
找到了匹配的文本固翰,則返回一個(gè)結(jié)果數(shù)組狼纬,否則返回 null
- 非全局匹配的情況
- 多次運(yùn)行返回同一個(gè)值,即字符串中第一個(gè)被匹配到的結(jié)果
- 返回一個(gè)數(shù)組骂际,第一個(gè)元素是與正則表達(dá)式匹配的文本疗琉,第二個(gè)元素是正則中第一個(gè)子表達(dá)式匹配的結(jié)果(如果有的話),第三個(gè)元素是是正則中第一個(gè)子表達(dá)式匹配的結(jié)果(如果有的話)歉铝,以此類推
var reg = /\d(\D)(\d)/;
var r = reg.exec('a1b2c3');
console.log(r); // ["1b2", "b", "2"]
r=reg.exec('a1b2c3');
console.log(r); // ["1b2", "b", "2"]
- 全局匹配的情況
- 當(dāng)正則對象為全局匹配盈简,執(zhí)行
exec()
方法時(shí),它會(huì)在RegExp實(shí)例的lastIndex
屬性指定的字符處開始檢索字符串太示,當(dāng)exec()
找到了與表達(dá)式相匹配的文本時(shí)柠贤,在匹配后,它將把RegExp實(shí)例的lastIndex
屬性設(shè)置為匹配文本的最后一個(gè)字符的下一個(gè)位置类缤。 - 可以通過反復(fù)調(diào)用
exec()
方法來遍歷字符串中的所有匹配文本臼勉,當(dāng)exec()
再也找不到匹配的文本時(shí),它將返回null餐弱,并把lastIndex
屬性重置為0
- 當(dāng)正則對象為全局匹配盈简,執(zhí)行
var reg=/\d/g;
while(r=reg.exec('a1b2c3')){
console.log(r.index+':'+r[0]); //"1:1" "3:2" "5:3"
}
3. 字符串對象實(shí)例的方法
String.prototype.search(reg)
search()
方法用于檢索字符串中指定的子字符串(參數(shù)為子字符串)宴霸,或檢索與正則表達(dá)式相匹配的子字符串(參數(shù)為正則表達(dá)式),返回字符串中第一個(gè)匹配的位置膏蚓,若未找到瓢谢,返回-1
search()
方法不執(zhí)行全局匹配,它將忽略標(biāo)志g
降允,它同時(shí)忽略正則表達(dá)式對象的lastIndex
屬性恩闻,并且總是從字符串的開始進(jìn)行檢索,這意味著它總是返回字符串的第一個(gè)匹配的位置
console.log('a1b2c3'.search(/\d/g)); //1
String.prototype.match(reg)
match()
方法將檢索字符串剧董,以找到一個(gè)或多個(gè)與正則匹配的文本
-
非全局匹配的情況
- 如果regexp沒有標(biāo)志
g
幢尚,那么match()
方法就只能在字符串中執(zhí)行一次匹配破停。如果沒有找到任何匹配的文本,match()
將返回null尉剩。否則它將返回一個(gè)數(shù)組真慢,其中存放了與它找到的匹配文本有關(guān)的信息。 - 返回的結(jié)果數(shù)組的第一個(gè)元素存放的是匹配文本理茎,而其余的元素存放的是與正則表達(dá)式的子表達(dá)式匹配的文本(如果有的話)
- 如果regexp沒有標(biāo)志
-
全局匹配的情況
- 如果regexp具有標(biāo)志
g
黑界,則match()方法將執(zhí)行全局檢索,找到字符串中的所有匹配子字符串皂林,若沒有找到任何匹配的子串朗鸠,則返回 null。 - 如果找到了一個(gè)或多個(gè)匹配子串础倍,則返回一個(gè)數(shù)組
- 如果regexp具有標(biāo)志
var reg = /\d(\D)/;
console.log('a1b2c3'.match(reg)); //["1b", "b"]
var reg = /\d(\D)/g;
console.log('a1b2c3'.match(reg)); //["1b", "2c"]
字符串match()方法和正則exec()方法的區(qū)別
- match()是字符串的方法烛占,參數(shù)是正則;exec()是正則的方法沟启,參數(shù)是字符串
- 非全局匹配情況下忆家,二者結(jié)果相同
- 全局匹配且無子表達(dá)式情況下,exec()執(zhí)行一次得到的是第一個(gè)匹配的結(jié)果德迹,要想獲得所有結(jié)果芽卿,需要進(jìn)行遍歷;而match()得到的是所有匹配結(jié)果組成的數(shù)組
- 全局匹配且有子表達(dá)式的情況下胳搞,exec()執(zhí)行一次得到的是第一個(gè)匹配到的結(jié)果和所有子表達(dá)式結(jié)果組成的數(shù)組卸例,而match()方法會(huì)忽略子表達(dá)式,返回的是所有匹配到的結(jié)果組成的數(shù)組
//非全局且無子表達(dá)式
var reg = /\D\d/;
var str = 'a1b2c3';
console.log(reg.exec(str)); //["a1"]
console.log(str.match(reg)); //["a1"]
//非全局且有子表達(dá)式
var reg = /\D(\d)/;
var str = 'a1b2c3';
console.log(reg.exec(str)); //["a1", "1"]
console.log(str.match(reg)); //["a1", "1"]
//全局且無子表達(dá)式
var reg = /\D\d/g;
var str = 'a1b2c3';
console.log(reg.exec(str)); //["a1"]
console.log(reg.exec(str)); //["b2"]
console.log(str.match(reg)); //["a1", "b2", "c3"]
//全局且有子表達(dá)式
var reg = /\D(\d)/g;
var str = 'a1b2c3';
console.log(reg.exec(str)); //["a1", "1"]
console.log(reg.exec(str)); //["b2", "2"]
console.log(str.match(reg)); //["a1", "b2", "c3"]
String.prototype.replace(reg|substr, replaceStr|function)
字符串替換方法流酬,返回一個(gè)由替換值(參數(shù)2)替換匹配的模式(參數(shù)1)后的新字符串
- 不改變原字符串
- 有兩個(gè)參數(shù)
- 第一個(gè)參數(shù)是要替換的部分币厕,可以傳入正則表達(dá)式或者字符串
- 第二個(gè)參數(shù)是替換為的部分,可以是一個(gè)字符串芽腾,或者一個(gè)回調(diào)函數(shù)
- 默認(rèn)情況下只替換匹配到的第一個(gè)旦装,除非在正則中使用修飾符
g
1. 第二個(gè)參數(shù)為字符串的情況
第二個(gè)參數(shù)中,如果是字符串摊滔,可以使用如下幾個(gè)特殊模板字符
-
$$
插入一個(gè) "$"阴绢。 -
$&
插入匹配的子串。 - $`插入當(dāng)前匹配的子串左邊的內(nèi)容艰躺。
-
$'
插入當(dāng)前匹配的子串右邊的內(nèi)容呻袭。 -
$n
假如第一個(gè)參數(shù)是 RegExp對象,并且 n 是個(gè)小于100的非負(fù)整數(shù)腺兴,那么插入第n個(gè)子表達(dá)式左电。注意:索引是從1開始
var str = 'abc123def';
var reg = /(\d)\d(\d)/;
console.log(str.replace('123', '$$')); //"abc$def"
console.log(str.replace('123', '0$&4')); //"abc01234def"
console.log(str.replace('123', '$`')); //"abcabcdef"
console.log(str.replace('123', "$'")); //"abcdefdef"
console.log(str.replace(reg, '$1' + '0' + '$2')); //"abc103def"
例子1:給兩個(gè)單詞交換位置
//交換兩個(gè)單詞位置
var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr); // Smith, John
2. 第二個(gè)參數(shù)為函數(shù)的情況
str.replace(reg, fn)
可以指定一個(gè)函數(shù)作為第二個(gè)參數(shù),該函數(shù)的返回值作為替換字符串,當(dāng)匹配執(zhí)行后篓足,該函數(shù)就會(huì)執(zhí)行
注意:如果第一個(gè)參數(shù)是正則表達(dá)式段誊,并且其為全局匹配模式,那么這個(gè)方法將被多次調(diào)用栈拖,即每次匹配都會(huì)被調(diào)用
該回調(diào)函數(shù)可以接收四個(gè)參數(shù)
- 參數(shù)1:就是匹配到的字符串(類似上述模板字符的$&)
- 參數(shù)2(可能有多個(gè)连舍,取決于正則中是否有分組):如果參數(shù)1是正則且有分組,則參數(shù)2就是對應(yīng)的一個(gè)或者多個(gè)分組結(jié)果
- 參數(shù)3:是被匹配到的子串在字符串中的索引位置
- 參數(shù)4:原字符串
例子2:將字符串中的每個(gè)數(shù)字后添加0
var str = 'a1b2c3d4';
var newStr = str.replace(/\d/g, function(match, index, str){
//因?yàn)槿制ヅ鋾?huì)匹配到4次涩哟,因此會(huì)執(zhí)行4次console.log()
//match四次分別輸出:"1" "2" "3" "4"
//index四次分別輸出:1 3 5 7
//str每次都輸出:"a1b2c3d4"
console.log(match, index, str);
return match + 0; //給每個(gè)匹配到的字符串后面添加個(gè)0索赏,作為新字符串
});
console.log(newStr); //"a10b20c30d40"
例子3:給不同分組間添加'-'
function replacer(match, p1, p2, p3) {
//p1、p2贴彼、p3表示正則中匹配到的分組(子表達(dá)式)
console.log(p1, p2, p3); //"abc" "123" "#$*"
return p1 + '-' + p2 + '-' + p3;
}
var newString = 'abc123#$*'.replace(/([\D]*)(\d*)([\W]*)/, replacer);
console.log(newString); // abc-123-#$*
String.prototype.split(reg)
分割字符串潜腻,當(dāng)字符串作為參數(shù)無法滿足要求時(shí),也可以傳入正則對象作為參數(shù)锻弓,來將字符串分割為數(shù)組
'a1b2c3d'.split(/\d/); //["a", "b", "c", "d"]