JS筆記(15): 正規表示式

六兩發表於2019-04-26

一、正則的基礎概念

正則(Regular Expression):是一個處理字串的規則

  • 1)正則只能用來處理字串
  • 2)處理一般包含兩方面:
    • A:正則匹配:驗證當前字串是否符合某個規則
    • B:正則捕獲:把一個字串中符合規則的字元獲取到

學習正則其實就是在學習如何編寫規則,每一個正則都是由元字元修飾符兩部分組成

一、建立正則的兩種方式

  • let reg = /^\d+$/g; //字面量方式
  • let reg2 = new RegExp(''||//, 'g'); //建構函式方式 第一個引數可以放變數
  • 正則兩個斜槓包起來的都是元字元,斜槓後面出現的都是修飾符

二、常用的修飾符

常用的修飾符 全稱 含義
i ignoreCase 忽略大小寫匹配
m multiline 多行匹配
g global 全域性匹配
// m 修飾符 多行匹配
let str = `
    趙州橋
    長江大橋
    多孔橋
    南浦大橋
`
let reg = /橋$/mg;
console.log(str.match(reg)); //["橋", "橋", "橋", "橋"]
複製程式碼

三、常用的元字元:

1.特殊元字元
  • \d 0-9之間的一個數字
  • \D 非0-9之間的任意字元
  • \w 數字、字母、下劃線中的的任意一個字元 /[0-9a-zA-Z_]/
  • \W 非數字、字母、下劃線中的任意字元
  • \s 匹配任意一個空白字元,包括:
    • \t製表符[tab鍵四個空格]
    • 空格
    • \n換行符
// test() 方法用於檢測一個字串是否匹配某個模式.
let str = '1-7p';
let reg = /\b7p/;
console.log(reg.test(str)); //true
console.log(reg.exec(str)); //[7p...]
複製程式碼
  • \n 匹配一個換行符 (enter)
let str = 'b7\np';
let reg = /^b7\np$/;
console.log(reg.test(str)); //true
console.log(reg.exec(str)); //["b7↵p"...]
console.log(str.match(reg)); //["b7↵p"...]
複製程式碼
  • \r 匹配一個回車符
  • \ 轉義字元: 有兩個作用
    • 把一個普通字元轉義為特出字元,例如\d
    • 把有特殊含義的轉義為普通意思,例如:\. 此處的點不是任意字元,而是一個小數點
  • . 不僅是小數點,代表除了\n 以外的任意字元
let reg = /^.$/;
console.log(reg.test('n')); //true
console.log(reg.test('1')); //true
console.log(reg.test('\n')); //false
console.log(reg.test('nn')); //false 只能是一位
複製程式碼
  • ^ 以某個元字元開頭
  • $ 以某個元字元結尾
  • x|y|z x或者y中的任意一個(x和y是自定義的字母)
  • [xyz] x或者y或者z中的任意一個(xyz為自定義)
  • [^xyz] 非x\y\z的任意字元
  • [a-z] 獲取a-z中的任意一個字元 [0-9] <=> \d
  • [^a-z] 非a-z的任意字元
  • () 正則分組
  • (?:) 當前正則只匹配不捕獲
  • (?=) 正向預查
  • (?!) 負向預查
2.量詞元字元:讓其左邊的元字元出現多少次
  • * 出現0到多個字元
  • ? 出現0到1個字元
  • + 出現1到多個字元
  • {n} 出現n個字元
  • {n,} 出現n到多個字元
  • {n,m} 出現n到m個字元
// *可以出現0到多次
let reg = /\d*/;
console.log(reg.test('')); //true 
console.log(reg.test('52246')); //true 
複製程式碼
//+ 可以出現1到多次,但是不能一次都不出現
let reg = /\d+/;
console.log(reg.test('')); //false 
console.log(reg.test('2')); //true
複製程式碼
// ?可以出現0-1次
let reg = /^\d?$/; //?可以出現0-1個字元
console.log(reg.test('')); //true
console.log(reg.test('5')); //true
console.log(reg.test('5262')); //false
複製程式碼
//{n}可以出現n個字元
let reg = /^\d{2}$/; 
console.log(reg.test('')); //false
console.log(reg.test('2')); //false
console.log(reg.test('26')); //true
console.log(reg.test('2956')); //false
複製程式碼
//{n,}可以出現n到多個字元
let reg = /^\d{2,}$/;
console.log(reg.test('')); //false
console.log(reg.test('5')); //false
console.log(reg.test('861')); //true
複製程式碼
//{n,m}可以出現n次到m個字元
let reg = /^\d{2,4}$/; 
console.log(reg.test('')); //false
console.log(reg.test('5')); //false
console.log(reg.test('52')); //true
console.log(reg.test('946')); //true
console.log(reg.test('9411')); //true
console.log(reg.test('55555')); //false
複製程式碼
3. 普通元字元

只要在正則中出現的元字元(在基於字面量方式建立),除了特殊和有量詞的以外,其餘的都是普通元字元

四、 加^$和不加^$的區別

let reg = /\d+/; //=> 不加^和$,代表字元傳中只要包含xxx即可
console.log(reg.test('kl55ijs56k')); //true 包含0-9之間的任意數字
複製程式碼
let reg1 = /^\d+$/; //=> 加^和$,代表字元傳中必須以0-9中的任意數字為開頭和結尾
console.log(reg1.test('kl55ijs56k')); //false
console.log(reg1.test('5222')); //true
複製程式碼

去掉字串前後空格

//方案一: 獲取'a  b',去掉前後空格
let str = '           a  b       ';
//第一個for迴圈去掉了a前面的空格
for (var i = 0; i < str.length; i++) {
    if (str[i] !== ' ') {
        //如果迴圈到字串中各項不是空格,就強制停止整個迴圈
        break;
    }
}
str = str.substring(i);//此時 str用var i為全域性變數
//第二個for迴圈去掉了b後面的空格
for (var k = str.length - 1; k > 0; k--) {
    //從最後一位開始找,如果不是空格,就擷取第一項到索引那項
    if (str[k] !== ' ') {
        str = str.substring(0, k + 1);
        break;
    }
}
console.log(str); //a  b  去掉了前後空格
複製程式碼
//方案二: 獲取'a  b',去掉前後空格
let str = '           a  b       ';
str = str.trim(); //字串方法:去掉字串前後空格
console.log(str); //a  b  去掉了前後空格
複製程式碼
//方案三: 獲取'a  b',去掉前後空格
let str = '           a  b       ';
let reg = /^\s+|\s+$/g; //以空格開頭或者以空格結尾
console.log(str.replace(reg, ''));
複製程式碼

二、[]的細節 & ()的作用

一、中括號的一些特殊細節

1.[]中出現的元字元一般都是代表本身含義的
let reg = /^[.]+$/; //在這裡只是小數點
console.log(reg.test('n')); //false
console.log(reg.test('1')); //false
console.log(reg.test('\n')); //false
console.log(reg.test('nn')); //false
console.log(reg.test('.')); //true
複製程式碼

但也有特殊情況,例如:

let reg = /^[\d]+$/; //在這裡依然是表示0-9之間的任意數字
console.log(reg.test('2')); //true
console.log(reg.test('lks')); //false
複製程式碼
2.中括號出現的兩位數並不是兩位數,而是兩個數字中的任意一個
let reg = /^[18]$/; //只能是1或者8
console.log(reg.test('1')); //true
console.log(reg.test('8')); //true
console.log(reg.test('18')); //false

let reg1 = /[18]/; //包含1或者8就可以
console.log(reg1.test('1')); //true
console.log(reg1.test('8')); //true
console.log(reg1.test('18')); //true
console.log(reg1.test('958524')); //true
複製程式碼
let reg = /^[13-56]$/; // 不是13~56 而是1或者3~5或者6
console.log(reg.test('1')); //true
console.log(reg.test('8')); //true
console.log(reg.test('6')); //false
複製程式碼
// 一位數是正常的 從n到m
let reg = /^[2-5]$/;
console.log(reg.test('2')); //true
console.log(reg.test('8')); //false
console.log(reg.test('5')); //true
複製程式碼

=======

匹配18-65之間的方法:

18-19 1[89] 20-59 [2-5]\d 60-65 6[0-5]

let reg = /^( ( 1[89] ) | ( [2-5]\d ) | ( 6[0-5] ) ) $/; console.log(reg.test('19')); //true

需求:編寫一個規則,匹配"[object AAA]"

let reg = /^[object .+]$/; console.log(reg.test('[object AAA]')); //true

計算字串中的位元組長度(一個英文位元組為1,一箇中文為2)
let str = '這個case非常international';
let num = 0;
for (let item of str) {
    //[\u4e00-\u9fa5] 中文區間 如果字串中的各項為中文(即為true)
    if (/[\u4e00-\u9fa5]/.test(item)) {
        num += 2;
    }else{
        num += 1;
    };
};
複製程式碼

二、()分組的作用

  • 改變預設的優先順序
  • 分組捕獲
  • 分組引用
1)改變預設優先順序(提權)
//不加小括號的情況
let reg = /^12|14$/; // 12或者14或者以12開頭或者以14結尾的都可以
console.log(reg.test('12')); //true
console.log(reg.test('14'));//true
console.log(reg.test('1214'));//true
console.log(reg.test('1258465414'));//true
console.log(reg.test('914'));//true
console.log(reg.test('123'));//true
console.log(reg.test('12ko'));//true
console.log(reg.test('+kj14'));//true
console.log(reg.test('12dsjjkn14'));//true
複製程式碼
let reg = /^(12|14)$/; // 分組改變預設優先順序
console.log(reg.test('12')); //true
console.log(reg.test('14'));//true
console.log(reg.test('1214'));//false
console.log(reg.test('1258465414'));//false
console.log(reg.test('914'));//false
console.log(reg.test('123'));//false
console.log(reg.test('12ko'));//false
console.log(reg.test('+kj14'));//false
console.log(reg.test('12dsjjkn14'));//false
複製程式碼
let str = '2018---4//---/26//';
let reg = /(\d+)\D+(\d+)\D+(\d+)\D+/
let s = str.replace(reg,function($0,$1,$2,$3){
    console.log($0); // 2018---4//---/26//
    console.log($1); //2018
    console.log($2); //4
    console.log($3); //26
    return `${$1}${$2}${$3}日`
});
console.log(s); //2018年4月26日
複製程式碼

關於replace的兩個引數:請檢視文末關於replace的內容

2)分組引用
let reg = /^([a-z])([a-z])\2\1$/; //正則中出現的\1代表和第一個分組出現一模一樣的內容
console.log(reg.test('oppo')); //true
console.log(reg.test('poop')); //true
複製程式碼
編寫一個方法:判斷字串中那個數字最多,出現多少次
let str = '437826357384623537463363726573384633278467382';
let min = -Infinity; //定義一個負無窮大的數
str = str.split('').sort().join('');
// 把亂序字串用空字串分割成陣列,排序陣列,再轉成字串,此時字串為 '222223333333333333444445556666666777777788888'
/* 
    \d 1個數字 
    \d\1 2個一樣的數字
    \d\1+ 2個到多個一樣的數字
    /(\d)\1+/g 沒找到2個以上一樣的數字,函式就執行一次
*/
str.replace(/(\d)\1+/g, function ($0, $1) {
    // console.log($0); //22222  3333333333333  44444  555  6666666  7777777  88888
    // console.log($1); // 2 3 4 5 6 7 8
    if (min < $0.length) {
        min = $0.length;
        let index = $1
    };
})
console.log(min, index); // 13 "3"
複製程式碼
3)分組捕獲

正則捕獲使用字串的match方法(正則exec方法不常用)

  • 如果可以匹配,捕獲的結果是一個陣列,如果不能匹配獲取的結果是null
  • 如果只在匹配的時候,想要獲取大正則中部分資訊,我們可以把這部分使用小括號包起來,形成一個分組(即子項),這樣在捕獲的時候,不僅可以把大正則匹配的資訊捕獲到,而且還單獨的把小分組匹配的部分資訊也捕獲到了(分組捕獲)
  • 有時候寫小分組不是為了捕獲資訊,而是為了改變優先順序或者進行分組引用,此時我們可以在分組的前面加上?:,代表當前分組只匹配不捕獲
let str = '2019';
let reg = /(\d)+/;
console.log(str.match(reg)); 
// ["2019", "9", index: 0, input: "2019", groups: undefined] 
// 不僅把大正則的資訊捕獲到,子項的資訊也捕獲到
//注意:子項如果包了一個規則,在規則之後有量詞,那麼結果為最後一個
複製程式碼

三、常用的正規表示式

一、有效數字:

  • 可以出現 + - 號,可以沒有,也可以有一個
  • 整數 0 12 9 :一位或者多位數字,一位0-9 ,多位數字不能以0開頭
  • 小數部分:可能有可能沒有,小數點後面至少要有一位數字
//利用正則檢測有效數字
let reg = /^[+-]?(\d|[1-9]\d)(\.\d+)?$/
複製程式碼

二、手機號碼

  • 11位數字
  • 第二位:3456789
  • 以1開頭
let reg1 = /^1[3456789]\d{9}$/;
console.log(reg1.test('18704366271'));
複製程式碼

三、中文姓名[\u4E00-\u9FA5]

  • 中文漢字[\u4E00-\u9FA5]{2,}
  • 迪麗熱巴·迪力木拉提
//中文姓名 1)中文漢字[\u4E00-\u9FA5]{2,} 2)
let reg = /^[\u4E00-\u9FA5]{2,}((·)([\u4E00-\u9FA5]{2,}))?$/;
console.log(reg.test('湯姆')); //true

console.log(reg.test('湯姆·')); //false
console.log(reg.exec('湯姆·')); // null

console.log(reg.test('湯姆·漢克斯')); //true
console.log(reg.exec('湯姆·漢克斯'));
複製程式碼

四、郵箱

  • 數字 字母 下劃線 - .
  • .- 不能作為開頭,不能連續出現 - 或者 .
  • @後面(域名):xxx.xx.xx xxx.xx xxx.xx.xx.xx xxx-xxx-xx.xx.xx
let reg = /^\w+([-.]\w)*@[A-Za-z0-9]+([.-])[A-Za-z0-9]+)*(\.[A-Za-z0-9]+)$/
複製程式碼

五、身份證號碼

  • 前六位省市區
  • 年1800-1899 1900-1999 2000-2019
  • 月[01-12] 01-09 10-12
  • 日 01-31: 01-09 10-29 30-31
  • 最後一位是數字或者x或者X
let reg2 = /^\d{6}((18\d\d)|(19\d\d)|(20[01]\d))(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}[\dxX]$/;
console.log(reg2.test('220802199603241523'));
複製程式碼

四、正則捕獲的懶惰性

  • 正則匹配:寫一個規則驗證當前這個字串和規則是不是匹配 test()
  • 正則捕獲:把一個字串中所有和正則相匹配的字元獲取到 => exec() test()
  • 字串中的一些方法也能實現正則捕獲:match split replace

一、正則捕獲的懶惰性

基於exec可以實現正則捕獲

  • 1.如果當前字串和正則不匹配 => null
  • 2.如果匹配,捕獲的結果是一個陣列
    • 0:大正則捕獲的內容
    • index:正則捕獲的起始索引
    • input:原始操作的字串
  • 3.執行一次exec只能捕獲到第一個和正則匹配的內容,其餘匹配的內容還沒有捕獲到,而且執行多次也無效 => 正則捕獲的懶惰性

正則捕獲的懶惰性:只能捕獲到第一個匹配的內容,剩餘的預設捕獲不到

let str = 'hello2018hello2019';
let str1 = 'hellohello';
let reg = /\d+/;

console.log(reg.test(str)); //true
console.log(reg.test(str1)); //false
console.log(reg.exec(str1)); // null
console.log(reg.exec(str)); //["2018", index: 5, input: "hello2018hello2019", groups: undefined]
複製程式碼

二、正則懶惰性產生的原因

  • 正則懶惰性的原因:lastIndex不變
  • lastIndex 正則捕獲時候,下一次在字串中開始查詢的索引
let str = 'zhufeng2018zhufeng2019';
let reg = /\d+/;

console.log(reg.exec(str)); //=> 2018
console.log(reg.lastIndex); //=> 0
console.log(reg.exec(str)); //=> 2018
console.log(reg.lastIndex); //=>0

// 即使手動修改了lastIndex值 依舊無效
reg.lastIndex = 11;
console.log(reg.lastIndex); //=>0
複製程式碼

三、正則懶惰性的解決方案

// 解決正則懶惰性:加全域性修飾符g
let str = 'zhufeng2018zhufeng2019';
let reg = /\d+/g;
console.log(reg.lastIndex); //=> 0
console.log(reg.exec(str)); //=> 2018
console.log(reg.lastIndex); //=> 11
console.log(reg.exec(str)); //=> 2019
console.log(reg.lastIndex); //=>22
console.log(reg.exec(str)); //=> null
console.log(reg.lastIndex); //=>0
console.log(reg.exec(str)); //=> 2018
複製程式碼

四、編寫一個方法:執行一次即可獲取

let str = 'zhufeng2018zhufeng2019yangfan2020qihang2021';
let reg = /\d+/g;

RegExp.prototype.myExecAll = function(str){
    // 為了防止出現死迴圈,我們檢測一下正則是否加g,沒有加g只把第一次捕獲的結果返回即可
    if(!this.global){
        return this.exec(str);
    };
    //this:reg 當前操作的正則
    //執行exec開始捕獲,具體捕獲多少次不定,但是一直到捕獲不到內容(null)為止,期間把捕獲到的內容儲存到陣列中
    let result = [];
    let valAry = this.exec(str);
    while(valAry){ //=>this.lastIndex < str.length
        result.push(valAry[0]); //=>把每次捕獲到的結果第一項(具體捕獲的內容)儲存到容器中
        valAry = this.exec(str);
    };
    return result;
};
console.log(reg.myExecAll(str));
//["2018", "2019", "2020", "2021"]
複製程式碼

五、利用字串match方法,把捕獲到的字串統一儲存到一個陣列中

let str = 'zhufeng2018zhufeng2019yangfan2020qihang2021';
let reg = /\d+/g;
console.log(str.match(reg)); 
//["2018", "2019", "2020", "2021"]
複製程式碼

字串方法:match

實現了自己編寫的execAll處理的事情,但也要加全域性修飾符g,把所有匹配的內容都捕獲到,最後統一儲存到一個陣列中返回

五、正則捕獲的貪婪性

一、分組捕獲

match() 方法可在字串內檢索指定的值,或找到一個或多個正規表示式的匹配。

match 實現了自己編寫的execAll處理的事情,但也要加全域性修飾符g,把所有匹配的內容都捕獲到,最後統一儲存到一個陣列中返回

let str = 'zhufeng{2018}zhufeng{2019yangfan{2020}qihang{2021}';
let reg = /\{(?:\d+)\}/g; //大括號有特殊含義:{n}出現的次數
console.log(reg.exec(str));
//["{2018}", "2018", ...]

console.log(str.match(reg)); //=>{2018}", "{2019}", "{2020}", "{2021} 
複製程式碼
  • 在正則捕獲時,如果正則中存在分組,捕獲的時候不僅把大正則匹配到的字元捕獲到(陣列第一項),而且把小分組匹配的內容也單獨抽取出來(陣列中的第二項開始就是小分組捕獲的內容) => 分組捕獲
  • /\{(?:\d+)\}/g => ?: 是用來阻止分組捕獲內容的 “只匹配不捕獲”
match方法的侷限性:

console.log(str.match(reg)); //=>{2018}", "{2019}", "{2020}", "{2021}

match方法也有自己的侷限性,在正則設定了g,基於match捕獲的內容只有大正則匹配的,小分組的內容沒有單獨抽取出來

二、正則捕獲的貪婪性

每一次匹配捕獲的時候,總是捕獲到和正則匹配中最長的內容,例如:2 符合 \d+ 2018 也符合 \d+ ,但是捕獲的是最長的內容 2018

let str = 'zhufeng2018zhufeng2019';
let reg = /\d+/g;
console.log(reg.exec(str)); //["2018", ...]
複製程式碼

解決方案:在量詞元字元後面加? , 代表的不是出現0-1次,而是取消正則捕獲貪婪性

let str = 'zhufeng2018zhufeng2019';
let reg1 = /\d+?/g;
console.log(reg1.exec(str)); // ["2", ...]
複製程式碼

三、? 在正則中的作用

  • 1.量詞元字元:出現0-1次 /-?/ 讓減號出現或者不出現
  • 2.取消貪婪性:/\d+?/ 只捕獲最短匹配內容
  • 3.?: 只匹配不捕獲
    1. ?= 正向預查
    1. ?! 負向預查

六、更多的捕獲方式

一、關於test()exec()

  • 基於test進行匹配的時候,如果設定了gtest匹配也相當於捕獲,修改了lastIndex的值
let str = 'zhufeng2018zhufeng2019';
let reg = /\d+/g;
console.log(reg.test(str)); //true
console.log(reg.lastIndex); //11 
console.log(reg.exec(str));//["2019",...]
複製程式碼
let str = 'zhufeng2018';
let reg = /\d+/g;
console.log(reg.exec(str));//[2018] 把reg.lastIndex值修改了
console.log(reg.exec('zhufeng2018zhufeng2019')); //[2019] 雖然捕獲的不是同一個字串,但是正則是同一個,上一次正則處理的時候修改了它的lastIndex,也會對下一次匹配的字串產生影響
複製程式碼

二、捕獲方式一:RegExp.$1方式

  • RegExp.$1 把上一次匹配(test/exec)到的結果獲取到,獲取的是第一個小分組匹配的內容,大正則匹配的內容無法獲取,他是一個全域性的值,瀏覽器中$1只有一個,其他的正則操作也會覆蓋這個值,所以這種方式一般不用
let str = 'zhufeng2018peixun2019';
let reg = /(\d+)/g;
console.log(reg.test(str)); //true
console.log(RegExp.$1); //2018 

console.log(reg.test(str)); //true
console.log(RegExp.$1); //2019
console.log(reg.test(str));//false
console.log(RegExp.$1); //2019
console.log(reg.test(str));//true
console.log(RegExp.$1); //2018
複製程式碼

三、捕獲方式二:replace

replace:實現正則捕獲的方法(本身是字串替換)

// 需求:把所有的'zhufeng'替換成'zhufengpeixun'
let str = 'zhufeng2018zhufeng2019';
let reg = /(\d+)/g;
str = str.replace('zhufeng','zhufengpeixun'); //一次只能替換一個,第二次還是從索引[0]開始替換
複製程式碼
  • 真實專案中,需要基於正則來替換
let str = 'zhufeng2018zhufeng2019';
str = str.replace(/zhufeng/g,'zhufengpeixun');
console.log(str); //zhufengpeixun2018zhufengpeixun2019
複製程式碼

四、replace原理

//不常用
let str = 'zhufeng{val:2018}zhufeng{val:2019}';
reg = /\{val:(\d+)\}/g;

str = str.replace(reg,'#'); // 用reg正則和str字元進行匹配,匹配幾次就替換幾次,每一次都是當前“大正則”匹配的結果用第二個傳遞的字串替換掉了

console.log(str); //zhufeng#zhufeng#
複製程式碼
//不常見
let str = 'zhufeng{val:2018}zhufeng{val:2019}';
reg = /\{val:(\d+)\}/g;

str = str.replace(reg,'$1'); // $1不是拿這個字元替換掉大正則匹配的內容,此處的$1代表第一個分組匹配的內容,等價於 RegExp.$1
console.log(str); //zhufeng2018zhufeng2019
複製程式碼

原理:string.replace(要替換的字串||正則,替換成什麼||函式);

  • 1.reg和str匹配多少次,函式就被觸發執行多少次,而且傳遞了一些引數資訊值
  • 2.每一次arg儲存的資訊和執行exec捕獲的資訊相似(內建原理:每一次正則匹配的結果,都把函式執行,然後基於exec把本次匹配的資訊捕獲到,然後把捕獲的資訊傳遞給這個函式)
  • 3.每一函式返回的內容是什麼,就把當前大正則匹配的內容替換成什麼
//常用
let str = 'zhufeng{val:2018}zhufeng{val:2019}';
reg = /\{val:(\d+)\}/g;
str = str.replace(reg,(...arg) =>{
console.log(arg);
return 'AA';
});
console.log(str);//zhufengAAzhufengAA
複製程式碼
關於replace中的的兩個引數:
  • 當第二個引數為函式的時候(預設情況下)

    • 函式的第一個引數就是每次匹配到的結果
    • 函式的第二個引數index 正則捕獲的起始索印
    • 函式的第三個引數input 原始操作的字串
    • 函式的第四個(及以後)groups 引數undefined
  • 2.如果有小括號提權,則:

    • 函式的第一個引數就是每次匹配到的結果
    • 函式的第二個引數 第一個小括號匹配的內容
    • 函式的第三個引數 第二個小括號匹配的內容
    • ...以此類推,直到所有的小括號匹配完畢
    • 匹配完畢之後的引數依次為index,input,undefined
  • 此函式必須要有return,不然預設為undefined

  • 多個小括號巢狀的情況: /((\d+)\D+(\d+))\D+(\d+)\D+/

    • 從左向右,第一個外層小括號為第一個,第一個外層小括號內的第一個小括號為第二個,第一個外層小括號內的第二個小括號為第三個,第二個外層小括號為第四個,以此類推
let str = '2018---4//---/26//';
let reg = /(\d+)\D+(\d+)\D+(\d+)\D+/
let s = str.replace(reg,function($0,$1,$2,$3){
    console.log($0); // 2018---4//---/26//
    console.log($1); //2018
    console.log($2); //4
    console.log($3); //26
    return `${$1}${$2}${$3}日`
});
console.log(s); //2018年4月26日
複製程式碼
// 用*替換指定字
let str = '為人民服務,為人民奮鬥,為人民努力' 
let s = str.replace(/服務|奮鬥|努力/g,function($0,$1){
let temp = '';
for (let i = 0; i < $0.length; i++) {
    temp += '*';
};
console.log($0); //服務 奮鬥 努力
return temp
})  
console.log(s); // 為人民**,為人民**,為人民**
複製程式碼

相關文章