正則

定義:用來處理字符串的規(guī)則

1、匹配:判斷一個字符串是否符合我們制定的規(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、實例創(chuàng)建方式:
var reg=new RegExp('');

兩種創(chuàng)建方式的區(qū)別?

  • 1、字面量方式中出現(xiàn)的一切都是元字符,所以不能進行變量值的拼接,而實例創(chuàng)建的方式是可以的
var reg=/^\d+"+name+"\d+$/g;
reg.test('2000""nameeee"2001');//true;

每個正則表達式都是由元字符和修飾符組成的(在//之間有意義的一些字符)

1、具有特殊意義的元字符

  • \ :轉(zhuǎn)義字符,轉(zhuǎn)義后面字符所代表的含義
  • ^:以某一個元字符開始
  • $:以某一個元字符結(jié)尾
  • 點.:代表處理\n以外的任意字符
  • \n:匹配一個換行符
var reg=/^0.2$/;//以0開頭,以2結(jié)尾,中間可以是除了\n的任意字符
reg.test('0-2');//true
reg.test('0.2');//true
  • ():分組 ->把一個大正則劃分成幾個小正則
  • \w:數(shù)字、字母、下滑下中的任意一個字符-> [0-9a-zA-Z_]
  • \s:匹配一個空白字符 空格、一個指標符、換頁符
var reg=/^(\d+)abcd(\d+)$/;

- x|y:x或者y中的一個字符
- [xyz]:x y z中的其中一個字符
- [^xyz]:除了xyz中的任意一個字符
- [a-z]:a-z之間的任何一個字符
- [^a-z]:除了a-z之間的任何一個字符
- \d:一個0-9之間的數(shù)字  \D:除了0-9之間的數(shù)字以外的任何字符
- \b:一個邊界符 '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次
郵箱驗證
左邊:數(shù)字、字母、下劃線、.、-
var reg=/^[\w.-]+@[0-9a-zA-Z]+(\.[a-zA-Z]{2,4}){1,2}$/;
reg.test('liubingqun163@163.com');//true;

3、分組的作用一:改變x|y的默認的優(yōu)先級

var reg=/^18|19$/;
reg.test('189');//true;
var reg1=/^(18|19)$/;
reg1.test('189');//false;

exec正則的捕獲

捕獲的內(nèi)容格式:

1、捕獲到的內(nèi)容是一個數(shù)組
  • 數(shù)組中的第一項是當前大正則捕獲的內(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'];

為什么會出現(xiàn)上面的情況呢?因為正則的懶惰型

2、正則捕獲的特點:
  • 懶惰型->每一次執(zhí)行exec只捕獲第一個匹配的內(nèi)容,不進行任何處理的情況下,在執(zhí)行多次捕獲,捕獲的還是第一個匹配的內(nèi)容
  • lastIndex:是正則每一次捕獲在字符串中開始查找的位置,默認值是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'];

我們能看出來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,那該怎么辦?
  • 正則在匹配的時候,是按照最長的匹配結(jié)果來匹配的,這就是它的貪婪性。例如:2和2017都復(fù)合上面demo的reg,但是捕獲的是2017,。
  • 解決正則貪婪性的方法和解決懶惰型的方法一樣簡單,在==量詞元字符==后面加一個?即可,問號代表了取消捕獲時候的貪婪性
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簡潔很多,但是match中存在一些自己處理不了的問題

在分組捕獲時,match只能捕獲到大正則匹配的內(nèi)容,無法捕獲到小正則的內(nèi)容,下面學習分組

正則分組

  • 1、改變優(yōu)先級
  • 2、分組引用
var reg=/^(\w)\1(\w)\2$/;
console.log(reg.test('aaff'));//true
console.log(reg.test('a0f_'));//false
\1代表和第一個分組出現(xiàn)一模一樣的內(nèi)容;\2代表和第二個分組出現(xiàn)一模一樣的內(nèi)容
  • 3、分組捕獲 ->正則在捕獲的時候,不僅僅把大正則匹配的內(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ù)組中的第一項:大正則捕獲到的內(nèi)容
        第二項:第一個小正捕獲到的內(nèi)容
        第三項:第二個小正則捕獲到的內(nèi)容
        第四項:捕獲的開始項
        第五項:原始的輸入

如果正則中出現(xiàn)了 ?: ,代表只匹配,不捕獲

var reg=/^(\d{2})(?:\d{4})$/;
var str='122344';
console.log(reg.exec(str));
//["122344", "12", index: 0, input: "122344"]

下面我們再講講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ū)別在哪?來看下面的代碼,原因是只捕獲一次就捕獲到了所有的內(nèi)容,那么match和exec作用一樣,那什么時候作用不一樣呢?

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

如果我先替換掉字符串時,

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)實現(xiàn),但是怎么實現(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和我們自己通過exec捕獲到的結(jié)果非常類似(即使正則有分組,我們同樣可以通過arguments獲取到分組捕獲的內(nèi)容)
  • 3、return 返回的結(jié)果,相當于把當前這一次==大正則==捕獲的內(nèi)容替換掉

如果正則中存在小分組時,結(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ā)生了變化。          
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • --------------------------正則的作用--------------------------...
    G_whk閱讀 752評論 1 5
  • 一、正則初體驗 在軟件開發(fā)中,不管是Java、C#、JS、OC....基本上都會接觸到正則,不過大多數(shù)人都對正則并...
    iceman_dev閱讀 2,926評論 9 28
  • 初衷:看了很多視頻、文章,最后卻通通忘記了,別人的知識依舊是別人的,自己卻什么都沒獲得。此系列文章旨在加深自己的印...
    DCbryant閱讀 4,259評論 0 20
  • 正則 1.什么是正則:用來操作字符串的規(guī)則; 正則就是用來操作(校驗,捕獲)“字符串”的 1)校驗:返回布爾值 t...
    web前端ling閱讀 648評論 0 0
  • //正則:就是以個規(guī)則 用來處理字符串的一個規(guī)則 var reg =/\d/; reg.exec("1"); //...
    Kyle_kk閱讀 837評論 0 1

友情鏈接更多精彩內(nèi)容