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入門一書