定義:用來(lái)處理字符串的規(guī)則
1、匹配:判斷一個(gè)字符串是否符合我們制定的規(guī)則->test:reg.test(str)
2整胃、捕獲: 把字符串中符合我們正則規(guī)則的內(nèi)容捕獲到->reg.exec(str)
var reg=/\d/;
console.log(reg.exec('1'));//['1',index:0,input:'1'];
創(chuàng)建正則的兩種方式:
- 1、字面量創(chuàng)建:
var reg=/\d/;
- 2、實(shí)例創(chuàng)建方式:
var reg=new RegExp('');
兩種創(chuàng)建方式的區(qū)別贝攒?
- 1、字面量方式中出現(xiàn)的一切都是元字符,所以不能進(jìn)行變量值的拼接,而實(shí)例創(chuàng)建的方式是可以的
var reg=/^\d+"+name+"\d+$/g;
reg.test('2000""nameeee"2001');//true;
每個(gè)正則表達(dá)式都是由元字符和修飾符組成的(在//之間有意義的一些字符)
1蛮寂、具有特殊意義的元字符
- \ :轉(zhuǎn)義字符,轉(zhuǎn)義后面字符所代表的含義
- ^:以某一個(gè)元字符開始
- $:以某一個(gè)元字符結(jié)尾
- 點(diǎn).:代表處理\n以外的任意字符
- \n:匹配一個(gè)換行符
var reg=/^0.2$/;//以0開頭纯路,以2結(jié)尾宛瞄,中間可以是除了\n的任意字符
reg.test('0-2');//true
reg.test('0.2');//true
- ():分組 ->把一個(gè)大正則劃分成幾個(gè)小正則
- \w:數(shù)字、字母爱咬、下滑下中的任意一個(gè)字符-> [0-9a-zA-Z_]
- \s:匹配一個(gè)空白字符 空格尺借、一個(gè)指標(biāo)符、換頁(yè)符
var reg=/^(\d+)abcd(\d+)$/;
- x|y:x或者y中的一個(gè)字符
- [xyz]:x y z中的其中一個(gè)字符
- [^xyz]:除了xyz中的任意一個(gè)字符
- [a-z]:a-z之間的任何一個(gè)字符
- [^a-z]:除了a-z之間的任何一個(gè)字符
- \d:一個(gè)0-9之間的數(shù)字 \D:除了0-9之間的數(shù)字以外的任何字符
- \b:一個(gè)邊界符 'a1 b2 c3'
> []中的字符不需要轉(zhuǎn)義精拟,但是\w除外燎斩,[]中不能出現(xiàn)兩位數(shù)
年齡介于18~65之間虱歪;
var reg=/[18-65]/;//這樣寫肯定不行
var reg1=/^1[8-9]|[2-5][0-9]|6[0-5]/;
reg1.test('18');//true
2、代表出現(xiàn)次數(shù)的量詞元字符
- *:出現(xiàn)零次或多次
- +:出現(xiàn)一次到多次
- 栅表?:出現(xiàn)零次或者一次
- {n}:正好出現(xiàn)n次
- {n,}:出現(xiàn)n到多次
- {n,m}出現(xiàn)n到m次
郵箱驗(yàn)證
左邊:數(shù)字笋鄙、字母、下劃線怪瓶、.萧落、-
var reg=/^[\w.-]+@[0-9a-zA-Z]+(\.[a-zA-Z]{2,4}){1,2}$/;
reg.test('liubingqun163@163.com');//true;
3、分組的作用一:改變x|y的默認(rèn)的優(yōu)先級(jí)
var reg=/^18|19$/;
reg.test('189');//true;
var reg1=/^(18|19)$/;
reg1.test('189');//false;
exec正則的捕獲
捕獲的內(nèi)容格式:
1洗贰、捕獲到的內(nèi)容是一個(gè)數(shù)組
- 數(shù)組中的第一項(xiàng)是當(dāng)前大正則捕獲的內(nèi)容
- index :捕獲內(nèi)容在字符串中開始的索引位置
- input:捕獲的原始字符串
var reg=/\d+/;
var str='luck2017byby2016';
var res=reg.exec(str);
console.log(res);
//['2017',index:4,input:'luck2017byby2016'];
res=reg.exec(str);
console.log(res);
//['2017',index:4,input:'luck2017byby2016'];
為什么會(huì)出現(xiàn)上面的情況呢找岖?因?yàn)檎齽t的懶惰型
2、正則捕獲的特點(diǎn):
- 懶惰型->每一次執(zhí)行exec只捕獲第一個(gè)匹配的內(nèi)容敛滋,不進(jìn)行任何處理的情況下许布,在執(zhí)行多次捕獲,捕獲的還是第一個(gè)匹配的內(nèi)容
- lastIndex:是正則每一次捕獲在字符串中開始查找的位置绎晃,默認(rèn)值是0蜜唾;它跟懶惰型有直接關(guān)系
var reg=/\d+/;
var str='luck2017byby2016';
var res=reg.exec(str);
console.log(reg.lastIndex); //8
console.log(res);
//['2017',index:4,input:'luck2017byby2016'];
res=reg.exec(str);
console.log(reg.lastIndex); //8
console.log(res);
//['2017',index:4,input:'luck2017byby2016'];
我們能看出來(lái)lastIndex每次都一樣,那么該怎么處理呢
在正則后面加上字符g
修飾符:g(全局)箕昭、i(ignoreCase忽略大小寫)灵妨、m(multiline多行匹配)
var reg=/\d+/g;
var str='luck2017byby2016';
var res=reg.exec(str);
console.log(reg.lastIndex); //8
console.log(res);
//['2017',index:4,input:'luck2017byby2016'];
res=reg.exec(str);
console.log(reg.lastIndex); //16
console.log(res);
//["2016", index: 12, input: "luck2017byby2016"];
原理:加了全局修飾符g,正則每一次捕獲結(jié)束后落竹,我們的lastIndex的值都變?yōu)榱俗钚碌闹得诨簦乱淮尾东@從最新的位置開始查找,這樣就可以把所有需要捕獲的內(nèi)容都獲取到了
3述召、自己編寫程序獲取正則獲取的所有的內(nèi)容(一定不能忘記加g)
var reg=/\d+/g;
var str='luck2017byby2016';
var ary=[];
var res=reg.exec(str);
while(res){
ary.push(res[0]);
res=reg.exec(str);
}
console.log(ary);//['2016','2017']
4朱转、正則的貪婪性
- 如果我只想捕獲到2017中的2,那該怎么辦积暖?
- 正則在匹配的時(shí)候藤为,是按照最長(zhǎng)的匹配結(jié)果來(lái)匹配的,這就是它的貪婪性夺刑。例如:2和2017都復(fù)合上面demo的reg缅疟,但是捕獲的是2017,。
- 解決正則貪婪性的方法和解決懶惰型的方法一樣簡(jiǎn)單遍愿,在==量詞元字符==后面加一個(gè)存淫?即可,問(wèn)號(hào)代表了取消捕獲時(shí)候的貪婪性
var reg=/\d+?/g;
var str='luck2017byby2016';
var ary=[];
var res=reg.exec(str);
while(res){
ary.push(res[0]);
res=reg.exec(str);
}
console.log(ary);
//["2", "0", "1", "7", "2", "0", "1", "6"]
字符串中的match方法->把所有和正則匹配的字符都獲取到
看下面的match方法
var reg=/\d+/g;
var str='luck2017byby2016';
var ary=str.match(reg)
console.log(ary);//["2017", "2016"]
var reg=/\d+?/g;
var str='luck2017byby2016';
var ary=str.match(reg)
console.log(ary);//["2", "0", "1", "7", "2", "0", "1", "6"]
從示例中能看出match比exec簡(jiǎn)潔很多沼填,但是match中存在一些自己處理不了的問(wèn)題
在分組捕獲時(shí)桅咆,match只能捕獲到大正則匹配的內(nèi)容,無(wú)法捕獲到小正則的內(nèi)容坞笙,下面學(xué)習(xí)分組
正則分組
- 1岩饼、改變優(yōu)先級(jí)
- 2荚虚、分組引用
var reg=/^(\w)\1(\w)\2$/;
console.log(reg.test('aaff'));//true
console.log(reg.test('a0f_'));//false
\1代表和第一個(gè)分組出現(xiàn)一模一樣的內(nèi)容;\2代表和第二個(gè)分組出現(xiàn)一模一樣的內(nèi)容
- 3籍茧、分組捕獲 ->正則在捕獲的時(shí)候版述,不僅僅把大正則匹配的內(nèi)容捕獲到,而且還可以把小分組匹配的內(nèi)容捕獲到
var reg=/^(\d{2})(\d{4})$/;
var str='122344';
console.log(reg.exec(str));
//["122344", "12", "2344", index: 0, input: "122344"]
數(shù)組中的第一項(xiàng):大正則捕獲到的內(nèi)容
第二項(xiàng):第一個(gè)小正捕獲到的內(nèi)容
第三項(xiàng):第二個(gè)小正則捕獲到的內(nèi)容
第四項(xiàng):捕獲的開始項(xiàng)
第五項(xiàng):原始的輸入
如果正則中出現(xiàn)了 ?: ,代表只匹配硕糊,不捕獲
var reg=/^(\d{2})(?:\d{4})$/;
var str='122344';
console.log(reg.exec(str));
//["122344", "12", index: 0, input: "122344"]
下面我們?cè)僦v講match的梗院水;
var reg=/(\d{2})(\d{4})$/;
var str='122344';
console.log(str.match(reg));
//["122344", "12", "2344", index: 0, input: "122344"]
what?竟然和exec一樣的,到底區(qū)別在哪简十?來(lái)看下面的代碼,原因是只捕獲一次就捕獲到了所有的內(nèi)容檬某,那么match和exec作用一樣,那什么時(shí)候作用不一樣呢螟蝙?
var reg=/abc(\d+)/g;
var str='abc123abc456abc789'
console.log(reg.exec(str));//["abc123", "123", index: 0, input: "abc123abc456abc789"]
console.log(reg.exec(str))//["abc456", "456", index: 6, input: "abc123abc456abc789"]
console.log(reg.exec(str));//["abc456", "456", index: 6, input: "abc123abc456abc789"]
console.log(str.match(reg));//["abc123", "abc456", "abc789"]
我們能明顯的看到在全局g下恢恼,match捕獲到的是大正則匹配的內(nèi)容,沒有小分組胰默。如果沒有全局g,再看看代碼的執(zhí)行情況
var reg=/abc(\d+)/g;
var str='abc123abc456abc789'
console.log(reg.exec(str));//["abc123", "123", index: 0, input: "abc123abc456abc789"]
console.log(reg.exec(str))//["abc123", "123", index: 0, input: "abc123abc456abc789"]
console.log(reg.exec(str));//[["abc123", "123", index: 0, input: "abc123abc456abc789"]
console.log(str.match(reg));//["abc123", "123", index: 0, input: "abc123abc456abc789"]
replace
如果我先替換掉字符串時(shí)场斑,
var str='ab12ab23';
str=str.replace('ab','abcd');
console.log(str);//'abcd12ab23'
我們看到了replace只替換了一次,如果用正則替換呢牵署?
var str='ab12ab23';
str=str.replace(/ab/g,'abcd');
console.log(str);//'abcd12abcd23'
功能已經(jīng)實(shí)現(xiàn)漏隐,但是怎么實(shí)現(xiàn)的呢?
var str='ab12ab23';
str=str.replace(/ab/g,function(){
console.log(arguments);
return 'abcd'
})
str;//'abcd12abcd23'
arguments;//["ab", 0, "ab12ab23"]
//["ab", 4, "ab12ab23"]
- 1奴迅、首先我們和exec捕獲一樣青责,把所有和我們正則匹配的都捕獲到,讓后把捕獲的內(nèi)容替換成我們需要替換的新內(nèi)容
- 2取具、每次執(zhí)行匿名函數(shù)脖隶,里面?zhèn)鬟f的參數(shù)值arguments和我們自己通過(guò)exec捕獲到的結(jié)果非常類似(即使正則有分組,我們同樣可以通過(guò)arguments獲取到分組捕獲的內(nèi)容)
- 3暇检、return 返回的結(jié)果产阱,相當(dāng)于把當(dāng)前這一次==大正則==捕獲的內(nèi)容替換掉
如果正則中存在小分組時(shí),結(jié)果怎樣呢块仆?
var str='ab12ab23';
str=str.replace(/a(b)/g,function(){
console.log(arguments);
return 'abcd'
})
str;//'abcd12abcd23'
arguments;//["ab", "b", 0, "ab12ab23"]
//["ab", "b", 4, "ab12ab23"]
str沒有變化构蹬, 只是arguments發(fā)生了變化。