上面代码中,\uD83D\uDC2A是一个四个字节的 UTF-16 编码,代表一个字符。但是,ES5 不支持四个字节的 UTF-16 编码,会将其识别为两个字符,导致第二行代码结果为true。加了u修饰符以后,ES6 就会识别其为一个字符,所以第一行代码结果为false

    一旦加上u修饰符号,就会修改下面这些正则表达式的行为。

    (1)点字符

    点(.)字符在正则表达式中,含义是除了换行符以外的任意单个字符。对于码点大于0xFFFF的 Unicode 字符,点字符不能识别,必须加上u修饰符。

    1. var s = '𠮷';
    2. /^.$/.test(s) // false
    3. /^.$/u.test(s) // true

    上面代码表示,如果不添加u修饰符,正则表达式就会认为字符串为两个字符,从而匹配失败。

    (2)Unicode 字符表示法

    上面代码表示,如果不加u修饰符,正则表达式无法识别这种表示法,只会认为这匹配 61 个连续的u

    (3)量词

    使用u修饰符后,所有量词都会正确识别码点大于0xFFFF的 Unicode 字符。

    1. /a{2}/.test('aa') // true
    2. /𠮷{2}/.test('𠮷𠮷') // false
    3. /𠮷{2}/u.test('𠮷𠮷') // true

    (4)预定义模式

    u修饰符也影响到预定义模式,能否正确识别码点大于0xFFFF的 Unicode 字符。

    上面代码的\S是预定义模式,匹配所有非空白字符。只有加了u修饰符,它才能正确匹配码点大于0xFFFF的 Unicode 字符。

    1. function codePointLength(text) {
    2. var result = text.match(/[\s\S]/gu);
    3. return result ? result.length : 0;
    4. var s = '𠮷𠮷';
    5. s.length // 4
    6. codePointLength(s) // 2

    (5)i 修饰符

    有些 Unicode 字符的编码不同,但是字型很相近,比如,\u004B\u212A都是大写的K

    上面代码中,不加u修饰符,就无法识别非规范的K字符。

    (6)转义

    没有u修饰符的情况下,正则中没有定义的转义(如逗号的转义\,)无效,而在u模式会报错。

    1. /\,/u // 报错

    上面代码中,没有u修饰符时,逗号前面的反斜杠是无效的,加了u修饰符就报错。