前端基礎之正規表示式

成cheng發表於2018-07-07

幾種用法的區別

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這個字串只有一個開始的引號,沒有結束的引號了。
所以語法報錯。

相關文章