關於正則處理中文問題 —— u修飾符正則表達式
y表示sticky(粘連),全局匹配,必須從第一個開始匹配,連續匹配函數
const s = 'aaa_aa_a' const r1 = /a+/g //至關於^ $ const 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
g修飾符是從aaa下一個開始匹配,開始能夠不是a學習
y修飾符是從aaa下一個開始匹配,開始必需要是a,不是a就返回null編碼
例子:使用lastIndex屬性,能夠更好地說明y修飾符。spa
const REGEX = /a/g // 指定從2號位置(y)開始匹配 REGEX.lastIndex = 2 // 匹配成功 const match = REGEX.exec('xaya') // 在3號位置匹配成功 console.log(match.index) // 3 // 下一次匹配從4號位開始 console.log(REGEX.lastIndex) // 4 // 4號位開始匹配失敗 REGEX.exec('xaxa') // null上面代碼中,lastIndex屬性指定每次搜索的開始位置,g修飾符從這個位置開始向後搜索,直到發現匹配爲止。code
y修飾符一樣遵照lastIndex屬性,可是要求必須在lastIndex指定的位置發現匹配。blog
const REGEX = /a/y // 指定從2號位置開始匹配 REGEX.lastIndex = 2 // 不是粘連,匹配失敗 REGEX.exec('xaya') // null // 指定從3號位置開始匹配 REGEX.lastIndex = 3 // 3號位置是粘連,匹配成功 const match = REGEX.exec('xaxa') console.log(match.index) // 3 console.log(REGEX.lastIndex) // 4
多個字節的字符,unicode
中大於 \uffff
,ES5中沒有辦法正確匹配。也就是說,使用u修飾符會正確處理四個字節的UTF-16編碼。索引
𠮷U+20BB7
let s = '𠮷' let s2 = '\uD842\uDFB7' console.log(/^\uD842/.test(s2)) //true 只匹配了兩個字符,是不對的 console.log(/^\uD842/u.test(s2)) //false
點字符含義是除了換行符之外的任意單個字符,可是大於0xFFFF的單個字符點字符沒法識別unicode
console.log(/^.$/.test(s)) //false 匹配任意字符,是不對的 console.log(/^.$/u.test(s)) //true 匹配任意字符
console.log(/\u{20BB7}/u.test(s)) //true console.log(/\u{61}/u.test('a')) //true console.log(/\u{61}/.test('a')) //false
能夠計數rem
//𠮷{2} 表示要出現兩次 console.log(/𠮷{2}/u.test('𠮷𠮷')) //true console.log(/𠮷{2}/.test('𠮷𠮷')) //false 匹配不正確
另外,只有在使用u修飾符的狀況下,Unicode表達式當中的大括號纔會被正確解讀,不然會被解讀爲量詞。
/^\u{3}$/.test('uuu') // true
上面代碼中,因爲正則表達式沒有u修飾符,因此大括號被解讀爲量詞。加上u修飾符,就會被解讀爲Unicode表達式。
/\u{20BB7}{2}/u.test('𠮷𠮷') // true
使用 u 修飾符以後 Unicode 表達式+量詞也是能夠的。
console.log(/[a-z]/iu.test('\u212A')) // true console.log(/[a-z]/i.test('\u212A')) // false 雖然i是忽略大小寫的,可是仍是匹配不正確
u修飾符也影響到預約義模式,可否正確識別碼點大於0xFFFF的Unicode字符。
/^\S$/.test('𠮷') // false /^\S$/u.test('𠮷') // true
上面代碼的\S
是預約義模式,匹配全部不是空格的字符。只有加了u修飾符,它才能正確匹配碼點大於0xFFFF
的Unicode
字符。
利用這一點,能夠寫出一個正確返回字符串長度的函數。
function codePointLength(text) { const result = text.match(/[\s\S]/gu); return result ? result.length : 0; } const s = '𠮷𠮷'; console.log(s.length) // 4 const reals = codePointLength(s) console.log(reals) // 2