乐趣区

关于javascript:ES6八-RegExp

RegExp

  • sticky —— y 修饰符
  • 对于正则解决中文问题 —— u 修饰符

    • 多字节中文字符匹配
    • 点字符
    • 新增 unicode 码点去匹配中文字符
    • 量词
    • i 修饰符
    • 预约义模式
  • ES6-ES10 学习幅员

sticky —— y 修饰符

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 修饰符。

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 修饰符从这个地位开始向后搜寻,直到发现匹配为止。

y 修饰符同样恪守 lastIndex 属性,然而要求必须在 lastIndex 指定的地位发现匹配。

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

对于正则解决中文问题 —— u 修饰符

多个字节的字符,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 的单个字符点字符无奈辨认

console.log(/^.$/.test(s)) //false 匹配任意字符,是不对的
console.log(/^.$/u.test(s)) //true 匹配任意字符

新增 unicode 码点去匹配中文字符

console.log(/\u{20BB7}/u.test(s)) //true
console.log(/\u{61}/u.test('a')) //true
console.log(/\u{61}/.test('a')) //false

量词

能够计数

//????{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 表达式 + 量词也是能够的。

i 修饰符

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 修饰符,它能力正确匹配码点大于 0xFFFFUnicode字符。

利用这一点,能够写出一个正确返回字符串长度的函数。

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

学习幅员

退出移动版