原文連線:
對於要重複單個字元,非常簡單,直接在字元後加上限定符即可,例如 a+ 表示匹配1個或乙個以上的a,a?表示匹配0個或1個a, 這些限定符如下所示:
x ?x ,一次或一次也沒有
x *x ,零次或多次
x +x ,一次或多次
x x ,恰好 n 次
x x ,至少 n 次
x x ,至少 n 次,但是不超過 m 次
但是我們如果要對多個字元進行重複怎麼辦呢 此時我們就要用到分組,我們可以使用小括號"()"來指定要重複的子表示式,然後對這個子表示式進行重複,例如:(abc)? 表示0個或1個abc 這裡一 個括號的表示式就表示乙個分組 。
分組可以分為兩種形式,捕獲組和非捕獲組。
捕獲性分組工作模式()會把每個分組裡匹配的值儲存起來, 儲存在記憶體中。
比如利用捕獲性分組把 2010/11/12 轉成 2010-11-12
方法一:通過exec函式
let str = '2010/11/12
let pattern = /(\d+)\/(\d+)\/(\d+)/let arr =pattern.exec(str)
console.log(arr);
//['2010/11/12', '2010', '11', '12']
console.log(arr[0]); //
'2010/11/12' 匹配到的字串
console.log(arr[1]); //
'2010' 第乙個分組(\d+)的值
console.log(arr[2]); //
'11'
console.log(arr[3]); //
'12'
//這時候兩個分組的值都得到了,接下來用字串拼接法實現互換
let result = `$-$-$`
console.log(result)
//2010-11-12
方法二:通過屬性$1-9
let str = '2010/11/12
'let pattern = /(\d+)\/(\d+)\/(\d+)/pattern.test(str);
//這個地方必須執行正則匹配一次,方式不限,可以是test()、exec()、以及string的正則方式
console.log(regexp.$1) //
'2010' 第乙個分組([a-z]+)的值
console.log(regexp.$2) //
'11'
console.log(regexp.$3) //
'12'
let result = `$-$-$`
console.log(result)
//2010-11-12
方法三:通過string的replace()
let str = '2010/11/12
'let pattern = /(\d+)\/(\d+)\/(\d+)/let result = str.replace(pattern,"
$1-$2-$3
"); //
這裡的$1、$2與方法二里的regexp.$1、regexp.$2作用是相同的。
console.log(result) //
2010-11-12
非捕獲性分組工作模式下分組(?:)會作為匹配校驗,並出現在匹配結果字元裡面,但不作為子匹配返回
非捕獲組不會捕獲文字,也不會將它匹配到的內容單獨分組來放到記憶體中。所以,使用非捕獲組較使用捕獲組更節省記憶體
比如利用非捕獲性分組獲取字串000aaa111,而且只返回乙個值為aaa111的陣列:
//先看用捕獲性分組匹配會返回什麼
let str1 = '
000aaa111
';
let pattern = /([a-z]+)(\d+)/; //
捕獲性分組匹配
let arr =pattern.exec(str1);
console.log(arr)
//['aaa111','aaa','111'] 結果子串也獲取到了,這並不是我們想要的結果
//非捕獲性分組
let str2 = '
000aaa111';
let pattern2 = /(?:[a-z]+)(?:\d+)/; //
非捕獲性分組匹配
let arr2 =pattern2.exec(str2);
console.log(arr2)
//['aaa111'] 結果正確
前瞻 = 先行斷言
(?=) 正向前瞻 = 正向零寬先行斷言
(?!) 反向前瞻 = 負向前瞻 = 負向零寬先行斷言
後顧 = 後發斷言
(?<=) 正向後顧 = 正向零寬後發斷言
(?詳細解釋如下表所示:
(?=x )
零寬度正先行斷言。僅當子表示式 x 在 此位置的右側匹配時才繼續匹配。例如,/w+(?=/d) 與後跟數字的單詞匹配,而不與該數字匹配。此構造不會回溯。
(?!x)
零寬度負先行斷言。僅當子表示式 x 不在 此位置的右側匹配時才繼續匹配。例如,例如,/w+(?!/d) 與後不跟數字的單詞匹配,而不與該數字匹配 。
(?<=x)
零寬度正後發斷言。僅當子表示式 x 在 此位置的左側匹配時才繼續匹配。例如,(?<=19)99 與跟在 19 後面的 99 的例項匹配。此構造不會回溯。
(?零寬度負後發斷言。僅當子表示式 x 不在此位置的左側匹配時才繼續匹配。例如,(?
簡單來說,前瞻就是 看後面等於(?=), 後面不等於 (?!), 後顧就是 前面等於 (?<=), 後面不等於 (?
比如 (? 表示, eat 前面不能是aa, 後面必須是 milk
比如 (?<=aa)eat(?!milk) 表示 eat 前面必須是aa, 後面不能是milk
示例1 匹配字串:
let str1 = "vveatmilk
"let str2 = "
aaeatfood
"let patt1 = new regexp("(?"
); let patt2 = new regexp("
(?<=aa)eat(?!milk)");
let result1 =patt1.test(str1);
let result2 =patt2.test(str2);
console.log(result1)
//true
console.log(result2) //
true
示例2 匹配div標籤:
let str = "我是div
"let patt = str.match('
(?<=).*(?=)'
) console.log(patt)
//我是div
匹配div標籤 也可用 下面這種方式實現
let str = "我是div
"let patt = str.match('
(.*?)')
console.log(patt)
//我是div
js正則 斷言
字面量和實列兩種建立方法 var reg 123123123aaa.g 或 var val 匹配 var reg newregexp 123123123aaa.g 修飾符貪婪與惰性模式var val 12345678asd console.log exec a 0 123456789 console...
正規表示式基本用法(二) 斷言 分組
斷言 也叫零寬度正 先行斷言 表示式 表示匹配表示式前面的位置 例如 a z ing 可以匹配cooking singing 中的cook與sing 注意 先行斷言的執行步驟是這樣的先從要匹配的字串中的最右端找到第乙個ing 也就是先行斷言中的表示式 然後 再匹配其前面的表示式,若無法匹配則繼續查詢...
正規表示式入門 下 分組和斷言
為什麼這裡寫的是元素而不是字元呢?這就要引入分組的概念了,使用 將一塊表示式括起來,可以把這個整體當做乙個元素處理 例如 ab 可以將兩個字元ab作為乙個整體看待,這時量詞?表示的就是ab作為整體,要麼一起出現,要麼一起不出現 ab test abab true ab test aba false ...