[ JS 進階 ] test, exec, match, replace

上面這四個方法在js中用的不少,但有時對它們又不清晰,因此有必要來總結一下。html

對了,這篇文章可能會涉及到正則表達式相關知識,因此推薦沒有正則基礎的去看看這篇入門文章:正則表達式30分鐘入門教程,很經典的文章,反正個人正則就是從這裏學的,^▽^ 。正則表達式

用法介紹

注:patternRegExp的實例, strString的實例express

用法 說明 返回值
pattern.test(str) 判斷str是否包含匹配結果 包含返回true,不包含返回false
pattern.exec(str) 根據patternstr進行正則匹配 返回匹配結果數組,如匹配不到返回null
str.match(pattern) 根據pattern對str進行正則匹配 返回匹配結果數組,如匹配不到返回null
str.replace(pattern, replacement) 根據pattern進行正則匹配,把匹配結果替換爲replacement 一個新的字符串

RegExp對象方法

test()

字符串的test方法,比較經常使用在判斷語句中,最簡單的RegExp方法了,用於檢測一個字符串是否匹配某個模式:數組

RegExpObject.test(string)

若是字符串 string 中含有與 RegExpObject 匹配的文本,則返回 true,不然返回 false:函數

/\d/.test('asdf2') // --true   檢測字符串`'asdf2'`中是否函數數字

exec()

exec()方法功能很是強大,它是一個通用的方法方法,用於比較複雜的模式匹配或者是說你爲你提供更多的信息:spa

RegExpObject.exec(string)

若是在string中找到了匹配的文本,則返回一個包含這些文本的數組,否側返回null。這裏有幾個注意的地方:code

  1. 返回的數組的第一個元素是與整個正則匹配的文本
    而後數組的第二個元素是與整個正則的第一個子表達式(分組)相匹配的文本
    數組的第三個元素整個正則的第二個子表達式(分組)相匹配的文本,以此類推。regexp

    ```
    var result = /(\d+)-(\w+)/.exec('12-ab');
    console.log(result) // --> ["12-ab", "12", "ab", index: 0, input: "12-ab"] 
    //爲何上面返回的「數組」是那麼奇怪,按照[w3school][2]的說法就是:exec() 都會把完整的細節添加到它返回的數組中,這裏的細節指的就是index和input
    ```
    
    整個正則表達式匹配的文本:`"12-ab"`
    第一個子表達式匹配的文本:`"12"`
    第二個子表達式匹配的文本:`"ab"`
  2. 從上面返回的數組結果可知,數組添加了兩個額外的屬性,分別是:index, input
    index: 匹配文本的第一個字符的位置.
    input: 顧名思義,就是指輸入的總體的文本了.htm

    ```
    console.log(result.index) // --> 0
    console.log(result.input) // --> '12-ab'
    ```
  3. 執行exec函數時,儘管是全局匹配的正則表達式,可是exec方法只對指定的字符串進行一次匹配,
    獲取字符串中第一個與正則表達式想匹配的內容,而且將匹配內容和子匹配的結果存儲到返回的數組中,
    例如:/\d/g.exec('a22') ,返回的結果和上面的結果同樣: ["2"]對象

    /\d/g.exec('a22') // -->["2"]

深刻了解 exec()

深刻前看看RegExp的實例有哪些屬性:

圖片描述

  • global: 布爾值,表示是否設置了 g 標誌

  • ignoreCase: 布爾值,表示是否設置了 i 標誌

  • lastIndex: 搜索下一個匹配項時開始的位置,從0開始

  • multiline: 布爾值,表示是否設置了 m 標誌

  • source: 正則表達式的字符串表示

這裏稍微陌生一點的就是lastIndex屬性了,由於咱們不會顯示的須要用到它。但它仍是挺重要的:

例1:非全局匹配

圖片描述

var reg = /\d/;
//第一次匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//輸出
["1"]
  0
  
第二次匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//輸出
["1"]
  0

結論:

  1. 同一正則表達式,在非全局匹配模式下,每次實例的lastIndex屬性的值老是不變的(爲第一次找到匹配文本所在的位置,上面爲0 );

  2. 每次的匹配查找都是將lastIndex做爲起始位置的

例2:全局匹配

圖片描述

var reg = /\d/g;
//第一次匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//輸出
["1"]
  2
  
第二次匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//輸出
["2"]
  3 

第三次匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//輸出
["3"]
  4 

第四匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//輸出
null
  0

結論:

  1. 同一正則表達式,在全局匹配模式下,每次實例的lastIndex屬性的值爲匹配文本最後一個字符的下一個位置,上面例子中第一次匹配的時候最後一個字符位置爲1,則下一個位置爲:2

  2. 當 exec() 再也找不到匹配的文本時,它將返回 null,並把 lastIndex 屬性重置爲 0。

那當要獲取全局匹配的所有匹配項時,能夠經過循環來獲取:

var reg = /\d/g,
    result = [],
    crt;
while((crt = reg.exec('a123')) !== null){
    result = result.concat(crt)
};
result; //["1", "2", "3"]

String對象方法

1. match()

match() 方法可在字符串內檢索指定的值,或找到一個或多個正則表達式的匹配。在必定程度上它與上面的exec()有些類似,看一下吧:

例1:非全局匹配

var a = 'aaaa'.match(/\w/);
console.log(a); // ["a", index: 0, input: "aaaa"]

能夠看到,和exec()同樣,在數組中返回了index 和 input屬性。

例2:全局匹配

var a = 'aaaa'.match(/\w/g);
console.log(a); // ["a", "a", "a", "a"]

全局匹配就和exec方法有很大的不一樣了,他直接返回了全部符合匹配的子字符串的數組,另外,index和input屬性也不在其中了,因此這個方法效率可能會高一些,可是若是你須要更多的信息,則用exec()

2. replace()

這也是一個比較靈活經常使用的方法,它用於在字符串中用一些字符替換另外一些字符,或替換一個與正則表達式匹配的子串。

這個方法接收兩個必須的參數:

  • pattern: 這個參數能夠是字符串或是RegExp對象

  • replacement: 替換匹配項的字符串或處理函數的返回值

返回結果

  1. 當未找到匹配項的時候,返回原始字符串。

    'aaaa'.replace('bbb', 'b')     //"aaaa"
  2. 當pattern爲字符串或者爲非全局的RegExp對象的時候,只替換找到的第一項匹配項。

    'aaaa'.replace('a', 'b')     //"baaa"
        'aaaa'.replace(/\w/, 'b')    //"baaa"
  3. 當pattern爲全局的RegExp對象的時候,替換每一項匹配項。

    'aaaa'.replace(/\w/g, 'b')    //"bbbb"

replacement:爲函數時

'aaaa'.replace(/\w/g, function() {
    return 'b';
}); // "bbbb"

'aaaa'.replace(/\w/g, function(value) {
    return value.toUpperCase();
}); // "AAAA"

結論:

  1. 函數的返回值將做爲替換字符串

  2. 函數的第一個參數的值是每個匹配項,固然還有第二個參數,它的值是每一個匹配項在原始字符串的中位置,從0開始

特殊的 $:

replacement 中的 $ 字符具備特定的含義。以下表所示,它說明從模式匹配獲得的字符串將用於替換。

字符 替換文本
$一、$二、...、$99 regexp 中的第 1 到第 99 個子表達式相匹配的文本。
$& regexp 相匹配的子串
$` 位於匹配子串左側的文本
$' 位於匹配子串右側的文本
$$ 直接量符號

來一發:

//第一種狀況:
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$1'); // "aa"
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$2'); // "11"
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$3'); // "AA"
    //猜測 若是是 $4 回事什麼呢? undefined ? 
    'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$4'); // "$4"
    //因此,要是沒有該子項,則當成普通字符串處理了
    
//第二種狀況:
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$&'); //"aa11AA"

//第三種狀況:
'aa11AA'.replace(/(\d+)/g, '$`'); //"aaaaAA"

//第四種狀況:
'aa11AA'.replace(/(\d+)/g, "$'"); //"aaAAAA"

//第五種狀況:
'aa11AA'.replace(/(\d+)/g, '$$'); //"aa$AA"

先這樣吧,有問題再補充了,( ╯□╰ )

相關文章
相關標籤/搜索