ES6 正則的擴充套件 u y修飾符

2021-08-10 02:23:51 字數 4870 閱讀 3338

u修飾符

es6 對正規表示式新增了 u 修飾符,含義為 "unicode模式",用來正確處理大於 \uffff 的unicode字元。也就是說,會正確處理四個字元的 utf-16 編碼。

/^\ud83d/.test('\ud83d\udc2a') // true

/^\ud83d/u.test('\ud83d\udc2a') // false

上面**中,\ud83d\udc2a 是乙個四位元組的utf-16 編碼,代表乙個字元,但是,es5不支援四個位元組的 utf-16 編碼,會將其識別為兩個字元,導致第一行**結果為 true ,加了u修飾符以後,es6就會識別其為乙個字元,所以第二行**結果為false。

一旦加上 u 修飾符號,就會修改下面這些正規表示式的行為。

1)點字元

點(.)字元在正規表示式中,含義是除了換行符以外的任意單個字元。對於碼點大於 oxffff 的 unicode 字元,點字元不能識別,必須加上 u 修飾符。

var s = '吉';

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

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

上面**表示,如果不新增 u 修飾符,正規表示式就會認為字串為兩個字元,從而匹配失敗。

2) unicode 字元表示法

es6 新增了使用大括號表示unicode字元,這種表示法在正規表示式中必須加上 u 修飾符,才能識別當中的大括號,否則會被解讀為量詞。

/\u/.test('a') // false

/\u/u.test('a') // true

/\u/u.test('吉') // true

上面**表示,如果不加 u 修飾符,正規表示式無法識別 \u 這種表示法,只會認為這匹配61個連續的u。

3)量詞

使用 u 修飾符後,所有量詞都會正確識別碼點大於 oxffff 的unicode 字元。

/a/.test('aa') // true

/a/u.test('aa') // true

/吉/.test('吉吉') // false

/吉/u.test('吉吉') // true

4)預定義模式

u 修飾符也影響到預定義模式,能否正確識別碼點大於 oxffff 的unicode字元。

/^\s$/.test('吉') // false

/^\s$/u.test('吉') // true

上面**的 \s 是預定義模式,匹配所有不是空格的字元,只有加了u修飾符,才能正確匹配碼點大於 oxffff 的 unicode 字元。

利用這一點可以寫出乙個正確返回字串長度的函式。

function codepointlength(text) 

var s = '吉吉';

s.length // 4

codepointlength(s) // 2

5) i 修飾符

有些unicode編碼不同,但是字形很相近,比如,\u004b與 \u212a 都是大寫的 k。

/[a-z]/i.test('\u212a') // false

/[a-z]/iu.test('\u212a') // true

上面**中,不加 u 修飾符,就無法識別非常規的 k 字元。

y 修飾符

除了u 修飾符,es6還為正規表示式新增了 y 修飾符,叫做「粘連」修飾符。

y 修飾符的作用與 g 修飾符類似,也是全域性匹配,後一次匹配都從上一次匹配成功的下乙個位置開始。不同之處在於,g 修飾符只要剩餘位置中存在匹配就可,而 y 修飾符確保匹配必須從剩餘的第乙個位置開始,這也就是「粘連」的含義。

var s = 'aaa_aa_a';

var r1 = /a+/g;

var r2 = /a+/y;

console.log(r1.exec(s)) //["aaa", index: 0, input: "aaa_aa_a"]

console.log(r2.exec(s)) //["aaa", index: 0, input: "aaa_aa_a"]

console.log(r1.exec(s)) //["aa", index: 4, input: "aaa_aa_a"]

console.log(r2.exec(s)) //null

console.log(r1.exec(s)) //["a", index: 7, input: "aaa_aa_a"]

console.log(r2.exec(s)) //["aaa", index: 0, input: "aaa_aa_a"]

上面**有兩個正規表示式,乙個使用 g 修飾符,另乙個使用 y 修飾符,這兩個正規表示式各執行了三次,第一次執行的時候,兩者行為相同,剩餘字串都是 _aa_a。由於 g 修飾符沒有位置要求,所以第二次執行會返回結果,而 y 修飾符要求匹配必須從頭部開始,所以返回null。

如果改一下正規表示式,保證每次都能頭部匹配,y修飾符就會返回結果了。

var s = 'aaa_aa_a';

var r1 = /a+/g;

var r2 = /a+/y;

console.log(r1.exec(s)) //["aaa", index: 0, input: "aaa_aa_a"]

console.log(r2.exec(s)) //["aaa_", index: 0, input: "aaa_aa_a"]

console.log(r1.exec(s)) //["aa", index: 4, input: "aaa_aa_a"]

console.log(r2.exec(s)) //["aa_", index: 4, input: "aaa_aa_a"]

console.log(r1.exec(s)) //["a", index: 7, input: "aaa_aa_a"]

console.log(r2.exec(s)) //null

上面**每次匹配,都是從剩餘字串的頭部開始。

使用 lastindex 屬性,可以更好地說明 y 修飾符。

const regex = /a/y;

// 指定從2號位置開始匹配

regex.lastindex = 2;

// 不是粘連,匹配失敗

regex.exec('aya') // null

// 指定從3號位置開始匹配

regex.lastindex = 3;

// 3號位置是粘連,匹配成功

const match = regex.exec('xaxa');

match.index // 3

regex.lastindex // 4

實際上,y 修飾符號隱含了頭部匹配的標識 ^。

/b/y.exec('aba')

// null

上面**由與不能保證頭部匹配,所以返回 null ,y修飾符的設計本意,就是讓頭部匹配的標識 ^ 在全域性匹配中都有效。

在 split 方法中使用 y 修飾符,原字串必須以分隔符開頭。這也意味著,只要匹配成功,陣列的第乙個成員肯定是空字串。

'x##'.split(/#/y)

//["x", "", ""]

'##x'.split(/#/y)

// ["", "", "x"]

後續的分隔符只有緊跟前面的分隔符,才會被識別。

'#x#'.split(/#/y)

// ["", "x", ""]

'##'.split(/#/y)

// ["", "", ""]

下面是字串物件的 replace 方法例子

const regex = /a/gy;

'aaxa'.replace(regex, '-') // '--xa'

上面**中,最後乙個 a 因為不是出現在下一次匹配的頭部,所以不會被替換。

單單乙個 y 修飾符對,math 方法,只能返回第乙個匹配,必須與 g 修飾符聯用,才能返回所以匹配。

'a1a2a3'.match(/a\d/y) // ["a1"]

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

y 修飾符的乙個應用,是從字串提取 token(詞元),y 修飾符確保了匹配之間不會漏掉的字元。

const token_y = /\s*(\+|[0-9]+)\s*/y;

const token_g = /\s*(\+|[0-9]+)\s*/g;

tokenize(token_y, '3 + 4')

// [ '3', '+', '4' ]

tokenize(token_g, '3 + 4')

// [ '3', '+', '4' ]

function tokenize(token_regex, str)

return result;

}

上面**中,如果字串裡面沒有非法字元,y修飾符與g修飾符的提取結果是一樣的。但是,一旦出現非法字元,兩者的行為就不一樣了。

tokenize(token_y, '3x + 4')

// [ '3' ]

tokenize(token_g, '3x + 4')

// [ '3', '+', '4' ]

上面**中,g修飾符會忽略非法字元,而y修飾符不會,這樣就很容易發現錯誤。

es6的正則擴充套件筆記之修飾符

es6對於正規表示式新增了 u 修飾符和 y 修飾符。u 修飾符 含義為 unicode模式 用來正確處理大於 uffff的unicode字元。該修飾符不光會正確處理正規表示式,還會正確處理被匹配的字串。利用新增的正則例項物件屬性 unicode 可以判斷正規表示式是否設定了u修飾符。reg.uni...

ES6 正則的擴充套件

一,regexp 建構函式 es5中,regexp建構函式的引數有兩種情況。1,引數是字串,第二個引數表示正規表示式的修飾符 flag 2,引數是乙個正規表示式,返回乙個原有正規表示式的拷貝。es6中,如果regexp建構函式第乙個引數是乙個正則物件,那麼可以使用第二個引數指定修飾符。而且,返回的正...

ES6精華 正則擴充套件

本篇概括了es6中正規表示式新增部分的精華要點 最好有es5的基礎 使正則處於unicode模式。關於es6的字元擴充套件知識,可檢視這裡。處於unicode模式下的正則,可以正確識別32位 四位元組 字元。let c ud83d udc2a 32位字元 console.log s test c f...