ES6正則的擴展

1 RegExp構造函數
在ES5中,RegExp構造函數的參數有兩種情況:
第一種情況:參數是字符串,第二個參數表示正則表達式的修飾符(flag)

var regex = new RegExp("xyz", "i");
// 等價於
var regex = /xyz/i;      //  /xyz/i

第二種情況: 參數是一個正則表達式,直接表示正則表達式

var regex = new RegExp(/xyz/i);
// 等價於
var regex = /xyz/i;      //  /xyz/i

ES5不允許此時使用第二個參數添加修飾符

var regex = new RegExp(/xyz/, 'i');
// Uncaught TypeError: Cannot supply flags when constructing one RegExp from another

ES6改變了這種行爲。如果RegExp構造函數第一個參數是一個正則對象,那麼可以使用第二個參數指定修飾符。而且,返回的正則表達式會忽略原有的正則表達式的修飾符,只能使用新指定的修飾符

new RegExp(/abc/ig, 'i').flags
// "i"

2 u 修飾符
ES6對正則表達式添加了u修飾符,含義是”Unicode模式”,用來正確處理大於\uFFFF的Unicode字符。
(1)點(.)字符在正則表達式中,含義是出了換行符以外的任意單個字符。對於碼點大於0xFFFF的Unicode字符,點字符不能識別,必須加上u修飾符。

var s = '��';

/^.$/.test(s)          // false
/^.$/u.test(s)         // true

代碼表示,如果不添加u修飾符,正則表達式就會認爲字符串爲兩個字符,從而匹配失敗。
(2)Unicode字符表示法
ES6新增了使用大括號標識Unicode字符,這種表示法在正則表達式中必須加上u修飾符,才能識別當中的大括號,否則會被解讀爲量詞

/\u{61}/.test('a')      // false
/\u{61}/u.test('a')     // true

代碼表示,如果不加u修飾符,正則表達式無法識別\u{61}這種表示法,只會認爲這匹配61個連續的u。
(3)預定義模式
u修飾符影響到預定義模式,能否正確識別碼點大於0xFFFF的Unicode字符。

/^\S$/.test('��')      // false
/^\S$/u.test('��')         // true

利用此模式,寫出一個正確返回字符串長度的函數

function codePointLength(text) {
  var result = text.match(/[\s\S]/gu);
  return result ? result.length : 0;
}

var s = '����';

s.length                // 4
codePointLength(s)      // 2

3 y 修飾符
ES6還爲正則表達式添加了y修飾符,叫做”粘連”(sticky)修飾符。
y修飾符的作用與g修飾符類似,也是全局匹配,後一次匹配都從上一次匹配成功的下一個位置開始。不同之處在於,g修飾符只要剩餘位置中存在匹配就可,而y修飾符確保匹配必須從剩餘的第一個位置開始,這也就是”粘連”的含義。

var s = 'aaa_aa_a';
var r1 = /a+/g;
var r2 = /a+/y;

r1.exec(s) // ["aaa"]
r2.exec(s) // ["aaa"]

r1.exec(s) // ["aa"]
r2.exec(s) // null

以上有兩個正則表達式,一個使用g修飾符,一個使用y修飾符。這兩個正則表達式各執行了兩次,第一次執行的時候,兩者行爲相同,剩餘的字符串都是_aa_a。 由於g修飾符沒有位置要求,所以第二次執行會返回結果。而y修飾符要求匹配必須從頭部開始,所以返回null。
單單一個y修飾符對match方法,只能返回第一個匹配,必須與g修飾符聯用,才能返回所有匹配。

'a1a2a3'.match(/a\d/y)          // ["a1"]
'a1a2a3'.match(/a\d/gy)         // ["a1", "a2", "a3"]

4 sticky屬性
與y修飾符相匹配,ES6的正則對象多了sticky屬性,表示是否設置了y修飾符。

var r = /hello\d/y;
r.sticky                    // true

5 flags屬性
ES6爲正則表達式新增了flags屬性,會返回正則表達式的修飾符。

// ES5 的 source 屬性
// 返回正則表達式的正文
/abc/ig.source
// "abc"

// ES6 的 flags 屬性
// 返回正則表達式的修飾符
/abc/ig.flags
// 'gi'

6 s 修飾符:dotAll模式
正則表達式,點(.)是一個特殊字符,代表任意的單個字符。但是有兩個除外,一個是四個字節的字符,這個可以使用u修飾符解決。另一個是行終止符。
“行終止符”:
U+000A 換行符(\n)
U+000D 回車符(\r)
U+2028 行分隔符(line separator)
U+2029 段分隔符(paragraph separator)

/foo.bar/.test('foo\nbar')

// false

上面的代碼中,因爲.不匹配\n,所以正則表達式返回false
所以在ES2018中引入s修飾符,是的.可以匹配任意單個字符。注意: 基本上現在的瀏覽器都識別不了,畢竟ES2018的提案

/foo.bar/s.test('foo\nbar') 

// true

這種稱爲dotAll模式,即點(dot)代表一切字符。所以,正則表達式還引入了一個dotAll屬性,返回一個布爾值,表示該正則表達式是否處在dotAll模式。

const re = /foo.bar/s;

re.test('foo\nbar') // true
re.dotAll           // true
re.flags            // 's'

本博客內容摘抄自
阮一峯老師寫的ECMAScript6入門一書

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章