正則表達(dá)式學(xué)習(xí)筆記

正則表達(dá)式學(xué)習(xí)筆記

一篇記錄了學(xué)習(xí)正則表達(dá)式的筆記确虱。

1. 轉(zhuǎn)義字符

在 HTMl 中轉(zhuǎn)義字符以 & 符號(hào)開(kāi)頭,分號(hào);結(jié)尾例衍。比如小于號(hào)(<)就可以寫(xiě) &lt; 或者 &#60艘狭,空格可以寫(xiě)成 &nbsp;;

在 JavaScript 中轉(zhuǎn)義字符一般以反斜杠\開(kāi)頭,比如回車(也叫行結(jié)束符\r)囚霸、換行(\n)腰根、水平制表符(\t)、垂直制表符(\v)拓型、換頁(yè)符(\f)额嘿。反斜杠則以兩個(gè) \ 符號(hào)表示(即\\)瘸恼。

// 轉(zhuǎn)義雙引號(hào) 
var str = "abcde\"fg";       

// 反斜杠
var str2 = "abcd\\efg"; 

// 換行符
var str2 = "abcd\nefg";     

// 回車換行符
var str3 = "abcd\r\nefg";   

// 水平制表符,相當(dāng)于鍵盤(pán)上的 Tab 鍵 (\b 想當(dāng)于鍵盤(pán)上的退格鍵)
var str4 = "abcd\tefg";      

2. 兩種創(chuàng)建正則的方法

有兩種創(chuàng)建正則表達(dá)式的方式册养,一種是直接量(字面量)語(yǔ)法东帅,一種是通過(guò)內(nèi)置的對(duì)象 RegExp。

2.1 直接量語(yǔ)法

/pattern/attributes

比如匹配字符串 abc

var reg = /abc/, str = "abcde";

console.log(reg.test(str)); 
// true

檢查字符串 str 中是否存在 abc球拦。

2.2 通過(guò)內(nèi)置對(duì)象 RegExp

語(yǔ)法

new RegExp(pattern, attributes);

同樣是匹配字符串 abc

var reg = new RegExp("abc"), str = "abcde";

console.log(reg.test(str)); 
// true

參數(shù) pattern 的值可以是已有的正則表達(dá)式靠闭,但是如果在創(chuàng)建的時(shí)候不加關(guān)鍵字 new,返回的將是已有正則表達(dá)式的引用坎炼,而不是新創(chuàng)建的 RegExp 對(duì)象愧膀。

通過(guò)下面的兩個(gè)例子理解上一句話

  1. 使用 new 創(chuàng)建正則表達(dá)式:

    var reg = new RegExp("abc"), str = "abcde";
    
    var newReg = new RegExp(reg); 
    newReg.myAttr = "123";
    
    console.log(newReg.myAttr); 
    // "123"
    console.log(reg.myAttr);    
    // undefined
    
  2. 不使用 new 創(chuàng)建正則表達(dá)式:

    var reg = new RegExp("abc"), str = "abcde";
    
    var newReg = RegExp(reg); 
    newReg.myAttr = "123";
    
    console.log(newReg.myAttr); 
    // "123"
    console.log(reg.myAttr);    
    // "123"
    

2.3 參數(shù)

參數(shù) pattern 是一個(gè)字符串,指定了正則表達(dá)式的模式或其他正則表達(dá)式谣光。

參數(shù) attributes 是一個(gè)可選的字符串檩淋,包含屬性 "g"、"i" 和 "m"萄金,分別用于指定全局匹配蟀悦、區(qū)分大小寫(xiě)的匹配和多行匹配。ECMAScript 標(biāo)準(zhǔn)化之前捡絮,不支持 m 屬性熬芜。如果 pattern 是正則表達(dá)式莲镣,而不是字符串福稳,則必須省略該參數(shù)。

簡(jiǎn)單的說(shuō) pattern 就是我們寫(xiě)的規(guī)則瑞侮,而 attributes 是規(guī)則的修飾符的圆。

修飾符 g,即 global半火,是否執(zhí)行全局匹配越妈。

var reg = new RegExp("abc","g"), str = "abcdefgabc";

console.log(str.match(reg));   
// ["abc", "abc"]

// 查看正則表達(dá)式是否全局匹配
console.log(reg.global);      
// true 

使用全局匹配修飾符,匹配到兩個(gè) "abc"钮糖∶仿樱可以通過(guò) reg.global 去判斷當(dāng)前的正則表達(dá)式是否為全局匹配。

修飾符 i店归,即 ignoreCase阎抒,是否忽略大小寫(xiě)

var reg = new RegExp("abc","i"), str = "ABCDEFG";

console.log(str.match(reg));     
// ["ABC", index: 0, input: "ABCDEFG", groups: undefined]

// 查看正則表達(dá)式是否忽略大小寫(xiě)
console.log(reg.ignoreCase);    
// true  

使用忽略大小寫(xiě)修飾符消痛,匹配到 "abc"且叁。可以通過(guò) reg.ignoreCase 去判斷當(dāng)前的正則表達(dá)式是否忽略大小寫(xiě)秩伞。

修飾符 m逞带,即 multiline欺矫,是否以多行模式執(zhí)行模式匹配

var reg = new RegExp("abc","gm"), str = "abcdefghjk\nabcde";

console.log(str.match(reg));     
// ["abc","abc"]

// 查看正則表達(dá)式是否以多行模式執(zhí)行模式匹配
console.log(reg.multiline);    
// true   

使用多行匹配修飾符展氓,匹配到兩個(gè) "abc"穆趴。可以通過(guò) reg.multiline 去判斷當(dāng)前的正則表達(dá)式是否以多行模式執(zhí)行模式匹配遇汞。

注意:所有的字符串如果不手動(dòng)添加轉(zhuǎn)義字符 \n 都為一行毡代。

3. 字符組

在正則表達(dá)式中,字符組(一對(duì)方括號(hào)) [] 代表一位字符串的匹配范圍勺疼。

例如教寂,匹配字符串中三位連續(xù)的數(shù)字:

var reg = /[1234567890][1234567890][1234567890]/g, str = "12345asda7890";

console.log(str.match(reg)); 
// ["123", "789"]

當(dāng)匹配到符合的字符串片段后,就從當(dāng)前位置繼續(xù)向后匹配执庐,不會(huì)回頭再去匹配酪耕。

匹配所有的數(shù)字可簡(jiǎn)寫(xiě)為 [0-9],即 ASCII 碼中數(shù)字 0 到 9 范圍內(nèi)的所有內(nèi)容轨淌。

匹配所有的字母可簡(jiǎn)寫(xiě) [A-z]迂烁,所有的大寫(xiě)字母可簡(jiǎn)寫(xiě) [A-Z],所有的小寫(xiě)字母可簡(jiǎn)寫(xiě) [a-z]递鹉。

4. 元字符

在正則表達(dá)式中盟步,元字符(Metacharacter)是擁有特殊含義的字符。

4.1 元字符 .

元字符 .躏结,用于查找單個(gè)字符却盘,除了換行 \n 和行結(jié)束符 \r

var str = "That's hot!", patt1 = /h.t/g;

console.log(str.match(patt1));  
// "hat", "hot"

4.2 元字符 \w

元字符 \w媳拴,用于查找單詞字符(world)黄橘,相當(dāng)于 [0-9A-z_]

var str = "Give 100%!", patt1 = /\w/g;

console.log(str.match(patt1));   
// ["G", "i", "v", "e", "1", "0", "0"]

元字符 \W屈溉,用于查找非單詞字符塞关,相當(dāng)于 [^\w]

4.3 元字符 \d

元字符 \d子巾,用于查找數(shù)字帆赢,即 [0-9]

var str = "Give 100%!", patt1 = /\d/g;

console.log(str.match(patt1));   
// [ "1", "0", "0"]

元字符 \D线梗,用于查找非數(shù)字字符椰于,相當(dāng)于 [^\D]

4.4 元字符 \s

元字符 \s缠导,用于查找空白字符廉羔,即 [\r\n\t\v\f ]

空白字符可以是:

  • 空格符 (space character)
  • 制表符 \t (tab character)
  • 回車符 \r (carriage return character)
  • 換行符 \n (new line character)
  • 垂直換行符 \v (vertical tab character)
  • 換頁(yè)符 \f (form feed character)
var str = "Is this all\nthere is?", patt1 = /\s/g;

console.log(str.match(patt1));   
// [" ", " ", "?", " "]

元字符 \S,用于查找非空白字符憋他,相當(dāng)于 [^\s]孩饼。

4.5 元字符 \b

元字符 \b,用于匹配單詞邊界竹挡。

var str = "Is this all\nthere is?", patt1 = /\bt/g;

console.log(str.match(patt1));  
 // ["t", "t"]

元字符 \B镀娶,用于查找非單詞邊界,相當(dāng)于 [^\b]揪罕。

var str = "Is this all\nthere is?", patt1 = /(\bthis\b|\bt\B)/g;

console.log(str.match(patt1));   
// ["this", "t"]

4.6 元字符 \xxx

\xxx 元字符用于查找以八進(jìn)制數(shù) xxx 規(guī)定的字符梯码。

對(duì)字符串中的八進(jìn)制 127 (W) 進(jìn)行全局搜索:

var str = "Hello World or word!", patt1 = /\127/g;

console.log(str.match(patt1));   
// ["W"]

忽略大小寫(xiě)呢?

var str = "Hello World or word!", patt1 = /\127/gi;

console.log(str.match(patt1));   
// ["W", "W"]

4.7 元字符 \xdd

\xdd 元字符查找以十六進(jìn)制數(shù) dd 規(guī)定的字符好啰。

對(duì)字符串中的十六進(jìn)制 57 (W) 進(jìn)行全局搜索:

var str = "Hello World or word!", patt1 = /\x57/g;

console.log(str.match(patt1));   
// ["W"]

4.8 元字符 \uxxxx

\uxxxx 元字符用于查找以十六進(jìn)制數(shù) xxxx 規(guī)定的 Unicode 字符轩娶。

對(duì)字符串中的十六進(jìn)制 0057 (W) 進(jìn)行全局搜索:

var str = "Hello World or word!", patt1 = /\u0057/g;

console.log(str.match(patt1));   
// ["W"]

因?yàn)橛?jì)算機(jī)只能處理數(shù)字,如果要處理文本框往,就必須先把文本轉(zhuǎn)換為數(shù)字才能處理鳄抒。

Unicode(統(tǒng)一碼、萬(wàn)國(guó)碼椰弊、單一碼)是計(jì)算機(jī)科學(xué)領(lǐng)域里的一項(xiàng)業(yè)界標(biāo)準(zhǔn)许溅,包括字符集、編碼方案等秉版。Unicode 是為了解決傳統(tǒng)的字符編碼方案的局限而產(chǎn)生的贤重,它為每種語(yǔ)言中的每個(gè)字符設(shè)定了統(tǒng)一并且唯一的二進(jìn)制編碼,以滿足跨語(yǔ)言清焕、跨平臺(tái)進(jìn)行文本轉(zhuǎn)換并蝗、處理的要求。

 "\u54c8\u55bd" // 哈嘍

5. 量詞(限定符)

量詞耐朴,也叫限定符借卧,用于描述前面字符(分組)可以出現(xiàn)的次數(shù)盹憎。

注意:在此節(jié)中筛峭,變量 n 可以代表任何字符。

5.1 量詞 n+

量詞 n+陪每,匹配變量 n 至少出現(xiàn) 1 次影晓。

var str = "Hello World or word!", patt1 = /o+/g;

console.log(str.match(patt1));   
// ["o", "o", "o", "o"]

5.2 量詞 n*

量詞 n*,匹配變量 n 出現(xiàn) 0 次到無(wú)數(shù)次(至少出現(xiàn) 0 次)檩禾。

var str = "or oo", patt1 = /o*/g;

console.log(str.match(patt1));  
 // ["o", "", "", "oo", ""]   "oo" -> 貪婪匹配

5.3 量詞 n?

量詞 n?挂签,匹配變量 n 出現(xiàn) 0 次或 1 次。

var str = "or oo", patt1 = /o?/g;

console.log(str.match(patt1));   
// ["o", "", "", "o", "o", ""]

5.4 量詞 n{X}

量詞 n{X}盼产,匹配變量 n 出現(xiàn) X 次饵婆。

var str = "or oo ooo", patt1 = /o{2}/g;

console.log(str.match(patt1));   
// ["oo", "oo"]

5.5 量詞 n{X,Y}

量詞 n{X,Y},匹配變量 n 出現(xiàn) X 次到 Y 次戏售。

var str = "or oo ooo", patt1 = /o{2,3}/g;

console.log(str.match(patt1));   
// ["oo", "ooo"]

5.6 量詞 n{X,}

量詞 n{X,}侨核,匹配變量 n 至少出現(xiàn) X 次草穆。

var str = "or oo ooo", patt1 = /o{1,}/g;

console.log(str.match(patt1));   
// ["o", "oo", "ooo"]

5.7 量詞 ^n

量詞 ^n,匹配任何開(kāi)頭為 n 的字符串搓译。

var str = "abc def", str2 = "db cefc", patt1 = /^d/g;

console.log(str.match(patt1));   
// null
console.log(str2.match(patt1));  
// ["d"]

字符串 "abc def"a 開(kāi)頭悲柱。

5.8 量詞 n$

量詞 n$,匹配任何結(jié)尾為 n 的字符串些己。

var str = "abc def", str2 = "ab defc", patt1 = /c$/g;

console.log(str.match(patt1));   
// null
console.log(str2.match(patt1));  
// ["c"]

量次 ^$ 同時(shí)出現(xiàn)豌鸡,字符串只能是中間的內(nèi)容

var str = "abcdabcd", str2 = "abcd", patt1 = /^abcd$/g;

console.log(str.match(patt1));   
// null
console.log(str2.match(patt1));  
// ["abcd"]

5.9 量詞 ?=n

量詞 ?=n,匹配任何其后緊接指定字符串 n 的字符串段标。

例如涯冠,對(duì)其后緊跟 "all" 的 "is" 進(jìn)行全局搜索:

var str="Is this all there is";
var patt1=/is(?= all)/g;

console.log(str.match(patt1));   
// ["is"]

量詞 ?=n,也稱為正向預(yù)查(正向斷言)逼庞。

5.10 量詞 ?!n

量詞 ?!n功偿,匹配任何其后沒(méi)有緊接指定字符串 n 的字符串。

對(duì)其后沒(méi)有緊跟 "all" 的 "is" 進(jìn)行全局搜索:

var str="Is this all there is";
var patt1=/is(?! all)/gi;

console.log(str.match(patt1));  
// ["Is", "is"]

量詞 ?!n往堡,也有稱為非正向預(yù)查(非正向斷言)械荷。

6. 分組與反向引用

限制單個(gè)字符的出現(xiàn)次數(shù),直接在后面加上量詞即可虑灰。但是如果我們要同時(shí)限制多個(gè)字符呢吨瞎?我們可以通過(guò)括號(hào) () 把需要一起限制的字符括在一起,再在括號(hào)的后面加上量詞穆咐。

var str = "aa1bba123bcda123123bbbba123123123b3w";
var reg = /a(123){1,3}b/g; 

console.log(str.match(reg)); 
// ["a123b", "a123123b", "a123123123b"]

用括號(hào) () 把多個(gè)字符包裹起來(lái)颤诀,這個(gè)行為稱之為分組,被括號(hào)包裹起來(lái)的字符被稱為子表達(dá)式对湃。

例如崖叫,/(abc)\d/g匹配所有 abc 后面緊跟一位數(shù)字的字符片段。

分組可以用來(lái)提取字符:

var reg = /(\d{4})-(\d{1,2})-(\d{1,2})/;
var str = "2019-1-9", str2 = "2019-1-19", str3 = "2018-11-19";

console.log(str.match(reg));
// ["2019-1-9", "2019", "1", "9", index: 0, input: "2019-1-9", groups: undefined]
console.log(str2.match(reg));
// ["2019-1-19", "2019", "1", "19", index: 0, input: "2019-1-19", groups: undefined]
console.log(str3.match(reg));
// ["2018-11-19", "2018", "11", "19", index: 0, input: "2018-11-19", groups: undefined]

6.1 可捕獲的分組

我們直接通過(guò)括號(hào) () 進(jìn)行的分組默認(rèn)就是可捕獲的拍柒。

通過(guò)反向引用可以引用前面子表達(dá)式匹配的內(nèi)容心傀。反向引用以反斜杠 \ 開(kāi)頭,后面緊跟數(shù)字 123456789... 拆讯,數(shù)字為幾就代表引用第幾個(gè)子表達(dá)式的值脂男。

例如,\1 匹配第一個(gè)子表達(dá)式中匹配的內(nèi)容:

var str = "aa asd dd";
var reg = /(\w)\1/g; 

console.log(str.match(reg)); 
// ["aa", "dd"]

子表達(dá)式的值可以重復(fù)引用:

var str = "aaaa";
var reg = /(\w)\1\1\1/g; 

console.log(str.match(reg)); 
// ["aaaa"]

如果引用的是不存在的分組:

var str = "aaaa\3", str2 = "aabb\3";
var reg = /(\w)\1(\w)\2\3/g; 

console.log(str.match(reg));   
// ["aaaa?"]
console.log(str2.match(reg));  
// ["aabb?"]

當(dāng)引用了不存在的子表達(dá)式時(shí)种呐,匹配反向引用的字符本身宰翅。例如, \3就配 \3爽室。

可捕獲的分組也可以替換字符:

var reg = /(\d{4})-(\d{1,2})-(\d{1,2})/;
var str = "2019-1-9", str2 = "2019-1-19", str3 = "2018-11-19";

console.log(str.replace(reg,'$1/$2/$3'));
// 2019/1/9
console.log(str2.replace(reg,'$1/$2/$3'));
// 2019/1/19
console.log(str3.replace(reg,'$1/$2/$3'));
// 2018/11/19

6.2 不可捕獲的分組

我們知道默認(rèn)的分組是可捕獲的汁讼。但是所有的分組都可以捕獲在某些情況下是不需要的。

可以使用非捕獲括號(hào) (?:n) 達(dá)到我們的目的,n 為我們自己的子表達(dá)式嘿架。

var str = "aa1bba123bcda123123bbbba123123123b3w";
var reg = /a(?:123){1,3}b/g; 

console.log(str.match(reg)); 
// ["a123b", "a123123b", "a123123123b"]

可捕獲的分組捕獲的內(nèi)容會(huì)被存儲(chǔ)在內(nèi)存中卜录,不可捕獲的分組則不會(huì)捕獲文本,也不會(huì)將它匹配到的內(nèi)容單獨(dú)分組來(lái)放到內(nèi)存中眶明。

所以艰毒,如果我們使用的分組不用捕獲應(yīng)該使用不可捕獲的分組,更節(jié)省內(nèi)存搜囱。

7. 或 與 非

7.1 或(分支) |

在正則表達(dá)式中丑瞧,管道符 | (分支)的意思,只要滿足一個(gè)分子就可匹配成功蜀肘。

管道符 | 可用于子表達(dá)式 () 中:

var reg = /(123|456|789)[A-z]/g, str = "123bb45ccc";

console.log(str.match(reg)); 
// ["123b"]

也可用于表達(dá)式(方括號(hào)) [] 中:

var reg = /[123|456|789][A-z]/g, str = "1aa4Ab5Cc6E";

console.log(str.match(reg)); 
// ["1a", "4A", "5C", "6E"]

甚至就寫(xiě)在正則中绊汹。例如,檢查一個(gè)字符串的首尾是否存在數(shù)字:

var reg = /^\d|\d$/g, str = "1ab";

console.log(reg.test(str)); 
// true

7.2 非 ^

符號(hào) ^ 在正則表達(dá)式不同的位置擁有不同的含義:

  • /^abc/ - 在正則表達(dá)式的 頭部 表示匹配以 abc 開(kāi)頭的字符串(符號(hào) $ 匹配字符串的結(jié)束)扮宠。
  • /[^abc]/ - 放在正則表達(dá)式的 字符組 中則表示匹配除了 abc 以外的所有字符(非)西乖。

放在正則表達(dá)式頭部:

var reg = /^abc/g, str = "abcdefg", str2 = "123abcdefg";

console.log(str.match(reg));   
// ["abc"]
console.log(str2.match(reg));   
// null

第二行的頭部也是可以匹配到的:

var reg = /^abc/gm, str = "123abcdefg\nabcs";

console.log(str.match(reg)); 
// ["abc"]

符號(hào) ^ 放在表達(dá)式中意思為 ,即匹配除了這些以外的所有字符

var reg = /[^abc]/g, str = "abcdefg";

console.log(str.match(reg)); 
// ["d", "e", "f", "g"]

8. 沒(méi)想好寫(xiě)啥

9. 貪婪匹配與非貪婪匹配

量詞 默認(rèn)使用的就是貪婪匹配坛增,它會(huì)盡可能多的去匹配符合規(guī)則的字符串获雕。

var str = "aaaaaaaaa", reg = /a+/g;

console.log(str.match(reg)); 
// ["aaaaaaaaa"]

貪婪匹配轉(zhuǎn)換為非貪婪匹配,在量詞后加上符號(hào) ? 即可收捣。

var str = "aaaaaaaaa", reg = /a+?/g;

console.log(str.match(reg)); 
// ["a", "a", "a", "a", "a", "a", "a", "a", "a"]
var str = "11222333", reg = /\d{2,3}?/g;

console.log(str.match(reg)); 
// ["11", "22", "23", "33"]
var str = "11222333", reg = /\d??/g;

console.log(str.match(reg)); 
// ["", "", "", "", "", "", "", "", ""]

量詞 n? 届案,表示匹配出現(xiàn) 0 次或者 1 次,再加上一個(gè)符號(hào) ? 轉(zhuǎn)換為非貪婪匹配罢艾,那么匹配的就是 0 次楣颠。

10. RegExp 對(duì)象屬性

global 屬性用于判斷某個(gè)正則表達(dá)式是否具有修飾符 g

ignoreCase 屬性用于判斷某個(gè)正則表達(dá)式是否具有修飾符 i咐蚯。

multiline 屬性用于判斷某個(gè)正則表達(dá)式是否具有修飾符 m童漩。

lastIndex 屬性標(biāo)示下一次匹配的字符位置。常與 exec() 方法一起出現(xiàn)春锋。

source 屬性用于返回模式匹配所用的文本矫膨。

一個(gè)例子加深理解:

var str = "www.abc.com\n123.ab.cn";
var reg = /\w\./gm;

console.log(reg.lastIndex);  // 0
console.log(str.match(reg)); // ["w.", "c.", "3.", "b."]
console.log(reg.global);     // true
console.log(reg.ignoreCase); // false
console.log(reg.multiline);  // true
console.log(reg.source);     // "\w\."

reg.lastIndex = 4;
console.log(reg.lastIndex);  // 4
console.log(str.match(reg)); // ["w.", "c.", "3.", "b."]

reg.lastIndex = 4;
console.log(reg.lastIndex); // 4
console.log(reg.exec(str)); // ["c.", index: 6, input: "www.abc.com?123.ab.cn", groups: undefined]
console.log(reg.lastIndex); // 8
console.log(reg.exec(str)); // ["3.", index: 14, input: "www.abc.com?123.ab.cn", groups: undefined]
console.log(reg.lastIndex); // 16
console.log(reg.exec(str)); // ["b.", index: 17, input: "www.abc.com?123.ab.cn", groups: undefined]
console.log(reg.lastIndex); // 19
console.log(reg.exec(str)); // null
console.log(reg.lastIndex); // 0

exec() 當(dāng)匹配到符合規(guī)則的字符時(shí)便會(huì)停下,等待下一次調(diào)用看疙,直到字符串匹配結(jié)束豆拨。

11. RegExp 對(duì)象方法

11.1 test() 方法

test() 方法用于檢測(cè)一個(gè)字符串是否匹配某個(gè)模式.

語(yǔ)法

RegExpObject.test(string)

如果字符串 string 中含有與 RegExpObject 匹配的文本,則返回 true能庆,否則返回 false。

比如脚线,檢索 "www"

var str = "www.abc.com";
var patt1 = /www/;

console.log(patt1.test(str));   
// true

11.2 exec() 方法

exec() 方法用于檢索字符串中的正則表達(dá)式的匹配搁胆。

語(yǔ)法

RegExpObject.exec(string)

如果 exec() 找到了匹配的文本,則返回一個(gè)結(jié)果數(shù)組。否則渠旁,返回 null攀例。

在上一次匹配的基礎(chǔ)上接著匹配。

var reg = /ab/g;
var str = "abababab";

console.log(reg.lastIndex); // 0 -> 當(dāng)前開(kāi)始匹配的索引位置
console.log(reg.exec(str)); // ["ab", index: 0, input: "abababab", groups: undefined]
console.log(reg.lastIndex); // 2
console.log(reg.exec(str)); // ["ab", index: 2, input: "abababab", groups: undefined]
console.log(reg.lastIndex); // 4
console.log(reg.exec(str)); // ["ab", index: 4, input: "abababab", groups: undefined]
console.log(reg.lastIndex); // 6
console.log(reg.exec(str)); // ["ab", index: 6, input: "abababab", groups: undefined]
console.log(reg.lastIndex); // 8
console.log(reg.exec(str)); // null
console.log(reg.lastIndex); // 0
console.log(reg.exec(str)); // ["ab", index: 0, input: "abababab", groups: undefined]

exec() 當(dāng)匹配到符合規(guī)則的字符時(shí)便會(huì)停下顾腊,等待下一次調(diào)用粤铭,直到字符串匹配結(jié)束。

reg.lastIndex 是可讀寫(xiě)的杂靶。

var reg = /ab/g;
var str = "abababab";

console.log(reg.lastIndex); // 0 -> 當(dāng)前開(kāi)始匹配的索引位置
console.log(reg.exec(str)); // ["ab", index: 0, input: "abababab", groups: undefined]
reg.lastIndex = 0;       
console.log(reg.exec(str)); // ["ab", index: 0, input: "abababab", groups: undefined]

注意:如果不加修飾符 g梆惯,永遠(yuǎn)從索引 0 開(kāi)始匹配。

11.3 exec() 方法與子表達(dá)式 ()

還是上面那個(gè)例子吗垮,但是使用 exec() 方法去匹配

var str = "aaaa", str2 = "aabb";
var reg = /(\w)\1(\w)\2/g; 

console.log(reg.exec(str2));   
// ["aabb", "a", "b", index: 0, input: "aabb", groups: undefined]

此類數(shù)組的第 0 個(gè)元素是與正則表達(dá)式相匹配的文本垛吗,第 1 個(gè)元素是與 RegExpObject 的第 1 個(gè)子表達(dá)式相匹配的文本(如果有的話),第 2 個(gè)元素是與 RegExpObject 的第 2 個(gè)子表達(dá)式相匹配的文本(如果有的話)烁登,以此類推怯屉。

index 屬性聲明的是匹配文本的第一個(gè)字符的位置。input 屬性則存放的是被檢索的字符串 string饵沧。

11.4 compile() 方法

compile() 方法用于在腳本執(zhí)行過(guò)程中編譯正則表達(dá)式锨络。

compile() 方法也可用于改變和重新編譯正則表達(dá)式。

該特性已經(jīng)從 Web 標(biāo)準(zhǔn)中刪除狼牺,雖然一些瀏覽器目前仍然支持它足删,但也許會(huì)在未來(lái)的某個(gè)時(shí)間停止支持,請(qǐng)盡量不要使用該特性锁右。

語(yǔ)法

RegExpObject.compile(regexp,modifier)
  • 參數(shù) regexp 為正則表達(dá)式失受。

  • 參數(shù) modifier 為修飾符。

不推薦compile方法咏瑟。你可以使用 RegExp 構(gòu)造函數(shù)來(lái)得到相同效果拂到。

12. 字符串上使用正則表達(dá)式

12.1 字符串的 match() 方法

同樣的例子使用 match() 方法:

var str = "aabb";
var reg = /(\w)\1(\w)\2/g; 

console.log(str.match(reg));   
// ["aabb"]

如果不加全局修飾符 g 呢:

var str = "aabb";
var reg = /(\w)\1(\w)\2/; 

console.log(str.match(reg));   
// ["aabb", "a", "b", index: 0, input: "aabb", groups: undefined]

加了全局修飾符后結(jié)果與使用 exec() 方法類似。

12.2 字符串的 search() 方法

search() 方法返回匹配到字符串的位置码泞。

var str = "123aabb";
var reg = /(\w)\1(\w)\2/; 

console.log(str.search(reg));  
// 3

如果匹配不到則返回 -1

var str = "123abcd";
var reg = /(\w)\1(\w)\2/; 

console.log(str.search(reg));   
// -1

12.3 字符串的 split() 方法

split() 方法以特定的規(guī)則去拆分字符串:

var str = "ab0c2de2f4gh5d";
var reg = /\d/g; 

console.log(str.split(reg));   
// ["ab", "c", "de", "f", "gh", "d"]

以數(shù)字為界限去拆分字符串

12.4 字符串的 replace() 方法

replace() 方法以特定的規(guī)則去替換字符串:

var str = "what is you name?";

console.log(str.replace("a","b"));   
// "whbt is you name?"

把第一個(gè) "a" 替換為 "b"兄旬。

注意,replace() 方法第一個(gè)參數(shù)不是正則表達(dá)式時(shí)余寥,無(wú)法訪問(wèn)全局领铐。

使用正則表達(dá)式:

var reg = /a/g; 
var str = "what is you name?";

console.log(str.replace(reg,"b"));   
// "whbt is you nbme?"

把所有的 "a" 替換為 "b"

replace() 方法可引用子表達(dá)式匹配到的值宋舷,例如绪撵,如何把形如 XXYY 的字符串變成 YYXX。

var reg = /(\w)\1(\w)\2/g; 
var str = "aabb 123 1122";

console.log(str.replace(reg,"$2$2$1$1"));   
// "bbaa 123 2211"

replace() 方法的第二個(gè)參數(shù)可以通過(guò) $1 去引用第一個(gè)子表達(dá)式匹配到的值祝蝠。 同理 $2 為第二個(gè)音诈。

把某個(gè)字符替換為 $:

// 在 `replace()` 方法中幻碱,符號(hào) `$` 有轉(zhuǎn)義的意思,若想把某個(gè)字符替換為 `$`细溅,最好寫(xiě)為 `$$`:
var reg = /(\w)\1/g; 
var str = "aabb 123 1122";

console.log(str.replace(reg,"$"));   // "$$ 123 $$"
console.log(str.replace(reg,"$$"));  // "$$ 123 $$"
console.log(str.replace(reg,"$1"));  // "ab 123 12"

replace() 方法可傳入回掉函數(shù):

var reg = /(\w)\1(\w)\2/g; 
var str = "aabb 123 1122";

console.log(str.replace(reg, function(val, $1, $2){
    // val 為全局結(jié)果   $1 為第一個(gè)子表達(dá)式匹配到的值   $2 ...
    return $2 + $2 + $1 + $1
}));   // "bbaa 123 2211"

13. 實(shí)例

實(shí)例 1褥傍,the-first-name 轉(zhuǎn)為 theFirstName

var reg = /-(\w)?/g; 
var str = "the-first-name";

console.log(str.replace(reg, function(val, $1){
    return $1 ? $1.toUpperCase() : ""
}));   // "theFirstName"

反向轉(zhuǎn)換:

var reg = /([A-Z])/g; 
var str = "theFirstName";

console.log(str.replace(reg, function(val, $1){
    return "-" + $1.toLowerCase()
}));  // the-first-name

實(shí)例 2,字符串簡(jiǎn)單去重 aaabbcccdd -> abcd

// 反向引用多個(gè)
var reg = /(\w)\1+/g; 
var str = "aaabbcccadd";

console.log(str.replace(reg, "$1"));   
// "abcd"

實(shí)例 3喇聊,格式化數(shù)字 100000000 -> 100.000.000

var reg = /\B(?=(\d{3})+(?!\d))/g; 
var str = "100000000000000";

console.log(str.replace(reg, "."));   
// "100.000.000.000.000"
var reg = /\B(?=(\d{3})+$)/g; 
var str = "100000000000000";

console.log(str.replace(reg, "."));   
// "100.000.000.000.000"
var reg = /(?=\B(\d{3})+$)/g; 
var str = "10000000000000000";

console.log(str.replace(reg, "."));   
// "10.000.000.000.000.000"

實(shí)例 4恍风,匹配成對(duì)的 HTML 標(biāo)簽

var reg = /<([^>]+)>[\w\W]*<\/\1>/g; 
var str = "<div><h1>asdasd</h1></div>", str2 = "<p>asdasd</p>", str3 = "<div>asdasd</p>";

console.log(str.match(reg));
// "<div><h1>asdasd</h1></div>"
console.log(str2.match(reg));   
// ["<p>asdasd</p>"]
console.log(str3.match(reg)); 
// null

標(biāo)簽中不包含標(biāo)簽:

var reg = /<([^>]+)>[^<>]*<\/\1>/g; 
var str = "<div><h1>asdasd</h1></div>", str2 = "<p>asdasd</p>", str3 = "<div>asdasd</p>";

console.log(str.match(reg));
// "<h1>asdasd</h1>"
console.log(str2.match(reg));   
// ["<p>asdasd</p>"]
console.log(str3.match(reg)); 
// null

14. 學(xué)習(xí)資料

w3school 的 RegExp 對(duì)象

MDN web docs

《JavaScript 正則表達(dá)式迷你書(shū)》

渡一教育-正則表達(dá)式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市誓篱,隨后出現(xiàn)的幾起案子朋贬,更是在濱河造成了極大的恐慌,老刑警劉巖燕鸽,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兄世,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡啊研,警方通過(guò)查閱死者的電腦和手機(jī)御滩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)党远,“玉大人削解,你說(shuō)我怎么就攤上這事」涤椋” “怎么了氛驮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)济似。 經(jīng)常有香客問(wèn)我矫废,道長(zhǎng),這世上最難降的妖魔是什么砰蠢? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任蓖扑,我火速辦了婚禮,結(jié)果婚禮上台舱,老公的妹妹穿的比我還像新娘律杠。我一直安慰自己,他們只是感情好竞惋,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布柜去。 她就那樣靜靜地躺著,像睡著了一般拆宛。 火紅的嫁衣襯著肌膚如雪嗓奢。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天胰挑,我揣著相機(jī)與錄音蔓罚,去河邊找鬼造锅。 笑死抱慌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铝量。 我是一名探鬼主播贡这,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼茬末,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了盖矫?” 一聲冷哼從身側(cè)響起丽惭,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辈双,沒(méi)想到半個(gè)月后责掏,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡湃望,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年换衬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片证芭。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瞳浦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出废士,到底是詐尸還是另有隱情叫潦,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布官硝,位于F島的核電站矗蕊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏氢架。R本人自食惡果不足惜傻咖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望达箍。 院中可真熱鬧没龙,春花似錦、人聲如沸缎玫。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赃磨。三九已至筝家,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邻辉,已是汗流浹背溪王。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工腮鞍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人莹菱。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓移国,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親道伟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子迹缀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容