正則表達式相信大多數開發者並不陌生,不少開發語言都提供了對正則表達式的支持。JavaScript也不例外。 可是對於前端開發者而言正則表達式是見得多用得少,現用現查,還停留在一個很初級的階段。一句話總結來講:很強大、很好用、可是我記不住。javascript
本系列文章的目的就是爭取讓每個系統看完系列文章的前端開發者,都能完全弄懂JavaScript中的正則表達式,讓它再也不是你平常開發和麪試中的短板。前端
首先咱們仍是再簡單介紹一下什麼是正則表達式(非初學者請直接略過)java
正則表達式(Regular Expression),常簡寫爲regex、regexp或RE。描述是:使用單個字符串來描述、匹配一系列符合某個句法規則的字符串(wiki),簡單來講就是使用某種規則去匹配符合預期結果的字符串。這裏面的規則就是咱們所說的字符串。面試
好比下面這個例子:/^[a-z0-9]+$/i
就是用來匹配只能以英文和數字組成的字符串。正則表達式
接下來來介紹一下RegExp對象,在JavaScript中使用RegExp對象來支持正則表達式。數組
實例化RegExp對象有2種方式函數
使用一個正則表達式字面量,以斜槓表示開始和結束。學習
var regex = /^[a-z0-9]+$/;
複製代碼
調用RegExp對象的構造函數測試
var regex = new RegExp('^[a-z0-9]+$');
複製代碼
對應的語法是這樣new RegExp(pattern, attributes);
其中第二個參數是可選參數,用來表示修飾符(後面介紹)。ui
var regex = new RegExp('^[a-z0-9]+$','i');
等價於
var regex = /^[a-z0-9]+$/i;
複製代碼
上面兩種實例化的方法是等價的,都新建了一個內容爲/^[a-z0-9]+$/i
的正則表達式對象。它們的主要區別是,第一種方法在引擎編譯代碼時,就會新建正則表達式對象,而第二種方法則會在運行時新建正則表達式對象,在正則表達式不發生變化時前者的效率較高,同時也更加直觀。
RegExp.prototype.ignoreCase:返回一個布爾值,表示是否設置了i修飾符。
RegExp.prototype.global:返回一個布爾值,表示是否設置了g修飾符。
RegExp.prototype.multiline:返回一個布爾值,表示是否設置了m修飾符。
屬性 | 修飾符 | 描述 |
---|---|---|
ignoreCase | i | 執行對大小寫不敏感的匹配 |
global | g | 執行全局匹配(查找全部匹配而非在找到第一個匹配後中止) |
multiline | m | 執行多行匹配 |
以上三個屬性都是與修飾符相關的,且都是隻讀的。
compile() 方法被用於在腳本執行過程當中(從新)編譯正則表達式。與RegExp構造函數基本同樣。 此方法已被廢棄。
test()方法返回一個布爾值,用來查看正則表達式與指定的字符串是否匹配。
當你想判斷一個字符串中是否包括另一個字符串時候,就可使用 test()(相似於 String.prototype.search() 方法),差異在於test()返回一個布爾值,而 search()返回索引或者-1(不包含)
let str = 'hello world!';
let result = /^hello/.test(str);
console.log(result); //true
//若是正則表達式是一個空字符串,則匹配全部字符串。
let str = 'hello world!';
let result = new RegExp('').test(str);
console.log(result); //true
//若是正則表達式帶有g修飾符,則每一次test()方法都從上一次結束的位置開始向後匹配。
//lastIndex屬性不只可讀,還可寫,能夠手動指定匹配位置。
var r = /o/g;
var s = 'hello world!';
console.log(r.lastIndex) //0
console.log(r.test(s))
console.log(r.lastIndex) //5
console.log(r.test(s))
console.log(r.lastIndex) //8
console.log(r.test(s))
複製代碼
exec()用來返回匹配結果。若是發現匹配,就返回一個數組,數組成員是匹配成功的子字符串,不然返回null。
var s = 'hello world!';
var r1 = /l/;
var r2 = /yyyyyy/;
console.log(r1.exec(s)) //["l"]
console.log(r2.exec(s)) //null
//若是正則表示式包含圓括號(即含有「組匹配」),則返回的數組會包括多個成員。第一個成員是整個匹配成功的結果,後面的成員就是圓括號對應的匹配成功的組。(關於分組捕獲會在後面的文章中講到)
var r = /^(\d{3})-(\d{3,8})$/;
var s = '010-12345';
console.log(r.exec(s)); // ['010-12345', '010', '12345']
//若是正則表達式帶有g修飾符,則每一次exec()方法都從上一次匹配成功結束的位置開始向後匹配。
複製代碼
在使用exec()這個方法時候,咱們會發現返回數組還包含如下兩個屬性:
屬性 / 索引 | 描述 |
---|---|
[0] | 匹配的所有字符串 |
groups([1]……) | 括號中的分組捕獲 |
index | 匹配到的字符位於原始字符串的基於0的索引值 |
input | 原始字符串 |
在JavaScript中的字符串的實例方法之中,有4種與正則表達式有關:
在字符串中執行查找匹配的String方法,返回一個數組,在未匹配到時會返回 null。
var s = 'hello world!';
var r = /o/g;
console.log(s.match(r)) // ["o", "o"]
console.log(r.exec(s)) // ["o"]
//能夠看到若是帶有g修飾符,match()與正則對象的exec方法行爲不一樣,會一次性返回全部匹配成功的結果。
//該方法會忽略 RegExp.lastIndex 設置的值,從起始位置檢索
複製代碼
在字符串中執行查找全部匹配的String方法,返回一個迭代器(iterator)。
//在 matchAll 出現以前,經過在循環中調用regexp.exec來獲取全部匹配項信息(regexp需使用/g)
const regexp = RegExp('foo*','g');
const str = 'table football, foosball';
let matches = str.matchAll(regexp);
console.log(matches)
複製代碼
在字符串中測試匹配的String方法,返回匹配到的位置索引,或者在失敗時返回-1。
'hello world!'.search(/o/)
//返回第一個知足條件的匹配結果在整個字符串中的位置,test()返回布爾值。
//該方法會忽略 RegExp.lastIndex 設置的值,從起始位置檢索
複製代碼
在字符串中執行查找匹配的String方法,而且使用替換字符串替換掉匹配到的子字符串。 str.replace(search, replacement) 接受兩個參數,第一個是正則表達式,第二個是替換的內容。
//正則表達式若是不加g修飾符,就替換第一個匹配成功的值,不然替換全部匹配成功的值。
console.log('hello world!'. replace(/o/,'a'))
console.log('hello world!'. replace(/o/g,'a'))
//replace()方法中的第二個參數中能夠含有變量符號」$」,格式爲 $ + n , n 從1開始計。其表明正則表達式的匹配被記住的第n個匹配字符串(即小括號的做用)
console.log('hello world!'.replace(/(\w+)\s(\w+)/, '$2 $1'))
複製代碼
按照給定規則進行字符串分割的String方法,返回一個數組,包含分割後的各個成員。
str.split(separator, [limit]) 該方法接受兩個參數,第一個參數是正則表達式,表示分隔規則,第二個參數是返回數組的最大成員數。
//該方法忽略附加參數g,即不管是全局匹配仍是非全局匹配都不會影響返回結果。
//該方法也會忽略 RegExp.lastIndex 設置的值,從起始位置檢索
console.log('hello world!'. split(/ /))
複製代碼
以上match(),matchAll(),search(),split(),replace()這些StringObj對象的方法,不會改變StringObj自己的值,而是將結果做爲返回值返回。 而且這些方法中的RegExp參數,也能夠用字符串參數替換。其返回結果,除了replace()方法,其餘的返回結果仍是和RegExp參數時的返回結果同樣。
在下一期中會給你們結合圖形化的方式介紹JavaScript中正則表達式匹配規則的相關內容。敬請期待!若是你有什麼好的建議歡迎留言給咱們。