幾種用法的區別
1、 match、replace
2、 test
3、 exec
1、match、replace的呼叫物件是字串, test,exec的呼叫物件是正規表示式物件。
2、test 返回結果是boolen值, exec返回的結果是匹配到的陣列(沒有匹配到返回null)
exec執行時,如果沒有子匹配項(即沒有括號的情況),無論有沒有引數g, 只返回一個匹配項,
加g與不加g的區別:
加g再下一次呼叫exec的時候,會從上一次匹配結束後的地方重新開始匹配(即lastIndex的值會變化),
不加g,每次都是從頭開始匹配。
3、match 執行的結果接近 exec。
區別如下:
* 當沒有子匹配項, 且非全域性匹配時, 結果一樣
* 當沒有子匹配項, 且全域性匹配時, 結果不一樣,match匹配所有項, 但是exec會從上一次匹配結束後的地方重新開始匹配(即lastIndex的值會變化)
* 當有子匹配項, 且非全域性匹配時, 結果一樣
* 當有子匹配項, 且全域性匹配時, 結果不一樣, match會忽略子匹配項, exec正確返回所有匹配到的結果。
結論:
exec沒有子匹配項的時候,只會返回第一個匹配到的陣列。
match在有子匹配項後,會匹配所有匹配項,不需要另外新增全域性匹配,新增了反倒是不對了。
關於match與exec的區別的例子可以參考這裡
replace深入理解
1、replace的呼叫物件是string;
2、兩個引數,
-第一個引數傳入的正規表示式(匹配規則);
- 第二個引數是:通過匹配規則匹配到後,想傳入的字串或者函式;
3、返回的是匹配後的字串。
參考的原文地址:https://www.jianshu.com/p/31b…
一個簡單的例子:
var str = `red+green+world`;
str.replace(/red/, blue); // 將通過正規表示式匹配到的結果以第2個引數替換
str.replace(/+/g, ` `); // 將所有的加號,以空格替換
關於第一個引數,正規表示式沒什麼可說的,
第2個引數,有點講究:
$& 第一個引數(規則)的結果
$` 第一個引數(規則)的結果的所有左邊的字串
$` 第一個引數(規則)的結果的所有右邊的字串
$1,$2,$3...$n 第一個引數(規則)的結果的對應的子字串
$&
$& 適用於沒有子表示式的情況
var sStr=`討論一下正規表示式中的replace的用法`;
sStr.replace(/正規表示式/,`《$&》`);
// 得到:"討論一下《正規表示式》中的replace的用法"
$`
var sStr=`討論一下正規表示式中的replace的用法`;
sStr.replace(/正規表示式/,`《$`》`);
// 得到:"討論一下《討論一下》中的replace的用法"
$`
匹配字串右邊的所有字元,注意,既然 $` 有單引號,那麼外面的引號必須雙引號,如果不可以雙引號,只能把 $` 的單引號轉義。
var sStr=`討論一下正規表示式中的replace的用法`;
sStr.replace(/正規表示式/,"《$`》");
// 得到:"討論一下《中的replace的用法》中的replace的用法"
$1, $2, $3, …, $n
依次匹配子表示式,$1匹配的是字串中匹配到的內容,不是正規表示式。
全域性匹配的情況沒寫,
@@...@@`markdown語法變成`<blink>...</blink>
var a = `@@aaa@@ @@bbb@@`;
a.replace(/"([^"]*)"/g,`<blink>$1</blink>`);
var sStr=`討論一下正規表示式中的replace的用法`;
sStr.replace(/(正則)(.+?)(式)/,"《$1》$2<$3>");
// 得到:"討論一下《正則》表達<式>中的replace的用法"
如果第2個引數是函式
先看arguments的用法:
var sStr=`討論一下正規表示式中的replace的用法`;
sStr.replace(/(正則).+?(式)/,function() {
console.log(arguments);
});
// ["正規表示式", "正則", "式", 4, "討論一下正規表示式中的replace的用法"]
引數分別為:
- 匹配到的字串(此例為”正規表示式”)
- 如果正則使用了分組匹配就為多個否則無此引數。(此例的引數就分別為 “正則”, “式”)
- 匹配字串的對應索引位置(也就是”正規表示式”的索引位置,此例為4)
- 原始字串
正規表示式引數
g全域性匹配,i忽略大小寫
不帶g的情況下,從左向右匹配,如果匹配到了則不在向右匹配了,
帶g的情況,則從頭到尾都匹配完,返回所有匹配到的資料。
元字元
16個元字元
元字元 名稱 匹配物件
. 點號 單個任意字元(除回車
、換行
、行分隔符u2028和段分隔符u2029外)
[] 字元組 列出的任意一個字元
[^] 排除型字元組 未列出的單個任意字元
? 問號 匹配0次或1次
* 星號 匹配0交或多次
+ 加號 匹配1次或多次
{min,max} 區間量詞 匹配至少min次,最多max次
^ 脫字元 行的起始位置
$ 美元符 行的結束位置
| 豎線 分隔兩邊的任意一個表示式
() 括號 限制多選結構的範圍,標註量詞作用的元素,為反向引用捕獲文字
1,2... 反向引用 匹配之前的第一、第二...組括號內的表示式匹配的文字
w 匹配字母或數字或下劃線或漢字
d 匹配數字
匹配單詞的開始或結束
s 匹配任意的空白符
特殊分組匹配(只匹配不捕獲)
(?:exp)
匹配exp,不捕獲,不分組
位置匹配(零寬斷言)
(exp)
匹配exp,並且分組
1,匹配某個字串前面的位置(?<=exp)
這個位置的前面能匹配exp(這個位置的前面是exp)
2,匹配exp後面的位置(?=exp)
這個位置的後面能匹配exp(這個位置的後面是exp)
3,匹配某個字串前面的位置(?<!exp)
這個位置的前面不能匹配exp(這個位置的前面不是exp)
4,匹配exp後面的位置(?!exp)
這個位置的後面不能匹配exp(這個位置的後面不是exp)
關於零寬斷言的一個例子
匹配三個字元img的隨機組合,但是不能重複var reg = /i|m|g|im|mi|ig|gi|mg|gm|img|igm|mig|mgi|gim|gmi/
;
上面這種寫法確實可以。
/^(?!([img])(?=.*1))[img]+$/
上面的正規表示式在正則鐵路圖中看的更清楚。
正則鐵路圖
理解:?!
這個位置的後面,不能滿足表示式([img])(?=.*1)
,才可以。
這個比較繞, ?=
,用它來理解, 這個位置的後面,需要滿足表示式([img])(?=.*1)
,才可以。
這個表示式是([img])(?=.*1)
;
先是匹配img其中一個,緊跟著的後面的字串中需要滿足1
,即是之前匹配成功後的img其中一個。([img])(?=.*1)
的意思也就是說, 必須重複出現i*i
,m*m
,g*g
這種情況,才滿足。
然後?!
,取反,不能重複出現i*i
,m*m
,g*g
這種情況,才滿足。
也就是說,在開始位置,不能重複出現i*i
,m*m
,g*g
這種情況。/^(?!([img])(?=.*1))[img]+$/
,不能滿足igg,能後面重複的情況。
/^(([img])(?!.*2))+$/
的理解:
通過正則鐵路圖理解([img])(?!.*2)
先是匹配img其中一個,緊跟著的後面的位置,後面的子符串中不能有2
,即是之前匹配成功後的img其中一個。然後整體向後迴圈檢驗不能出現重複字元。
split
split是根據指定的分隔符,將字串分隔成多個子字串,返回這些子字串構成的陣列。
split中使用正則來實現分割。
var colorText = "red,blue,green,yellow";
var colors3 = colorText.split(/[^,]+/); //["", ",", ",", ",", ""]
/[^,]+/
這個正規表示式的意思就是,不是,
的多個字元。
也就是說根據不是,
的多個字元,將colorText
分割。
不是,
的多個字元 指的就是red blue green yellow,
分割結果就是:`` (red) `,` (blue) `,` (green) `,` (yellow) ``
括弧中的就是指定的分割符,結果就是["", ",", ",", ",", ""]
。
轉譯
js中申明:
var str = `1/`;
會報錯,
但是
var str = `1`;
不會報錯,為什麼呢? 這個東東是可以轉譯其他特殊字元的,看下面這個,
var str = `1``;
當這麼申明後, var str = `1``
; 後面的單引號被
給轉譯成了一個普通的引號,就成了
var str = `1``
,
如果寫成var str = `1`, 由於
`後面的單引號被給轉譯成了一個普通的引號了, str這個字串只有一個開始的引號,沒有結束的引號了。
所以語法報錯。