JavaScript ES6 - 正则表达式扩展

正则扩展: 主要来与 ES5 做一个对比 (也就是语法的扩展)

1. ES6 正则新特性:

   1. 构造函数的变化

   2. 正则方法的扩展: 字符串支持的处理方法(注意字符串的处理方式扩展在下面各个知识点中, 并没有单独作为一个模块来分析)

   3. u 修饰符

   4. y 修饰符

   5. s 修饰符

如图所示:

大纲

1. 正则构造函数

{
  // 声明 ES5 中的正则对象, 看原来的构造函数是怎么写的
  /**
   * 1. 第一种写法:
   *    1. 接收两个参数
   *       1. ES5 中第一个参数是一个 '字符串', 第二个参数是 '修饰符'
   *       2. i: i修饰符就是忽略大小写的意思 (执行对大小写不敏感的匹配)
   *    2. 注意: ES5 中, 当两个参数时, 第一个参数必须是 '字符串', 不能是 '正则表达式', 否则会报错
   *
   * 2. test(): 检索字符串中指定的值; 返回 true 或 false。
   */
  let regex1 = new RegExp('syz', 'i')

  /**
   * 2. 第二种写法:
   *    1. 只接受一个参数, 即 '正则对象'
   *    2. 注意: ES5 中, 当参数为 '正则表达式' 时, 不允许添加第二个参数 。
   *
   */
  let regex2 = new RegExp(/xyz/i)

  console.log('ES5 正则构造函数: ', regex1.test('syz123'), regex2.test('xyz123'));
  // 打印结果:
  // ES5 正则构造函数:  true true
}

// ES6 中的正则对象, 增加了一种方式
{
  /**
   * 1. ES6 中允许第一个参数是 '正则对象', 第二个参数是 '修饰符';
   * 2. 第二个参数的 '修饰符' 会覆盖 第一个参数 '正则对象' 的修饰符;
   * 3. 注意<知识点>: 'flags' 是 ES6 新增属性, 用来获取正则表达式的 '修饰符' 。
   * 4. g: g 修饰符是 执行全局匹配 (查找所有匹配而非在找到第一个匹配后停止)。
   */
  let regex1 = new RegExp(/abc/ig, 'i');
  console.log('ES6 正则构造函数 -- 修饰符: ', regex1.flags);
  // 打印结果:
  // ES6 正则构造函数 -- 修饰符:  i
}

2. y 修饰符

{
  /**
   * +: n+ 量词, 匹配任何包含至少一个 n 的字符串 。
   * exec: exec 对象方法, 检索字符串中指定的值; 返回找到的值, 并确定其位置 。
   */
  let str1 = 'bbb_bb_b'
  let regexES5 = /b+/g; // ES5 中的写法
  let regexES6 = /b+/y; // ES5 中的写法

  console.log('第一次 &&& y 修饰符 -- : ', 'regexES5: ', regexES5.exec(str1), 'regexES6: ', regexES6.exec(str1));
  // 打印结果:
  // 第一次 &&& y 修饰符 -- :  regexES5:  ['bbb', index: 0, input: 'bbb_bb_b', groups: undefined] regexES6:  ['bbb', index: 0, input: 'bbb_bb_b', groups: undefined]

  console.log('第二次 &&& y 修饰符 -- : ', 'regexES5: ', regexES5.exec(str1), 'regexES6: ', regexES6.exec(str1));
  // 打印结果:
  // 第二次 &&& y 修饰符 -- :  regexES5:  ['bb', index: 4, input: 'bbb_bb_b', groups: undefined] regexES6:  null

  /**
   * 1. 第一次匹配的时候, 它们都匹配到 'bbb';
   * 2. 在第二次匹配的时候 'g' 修饰符能够匹配到 'bb', 而 'y' 修饰符没有匹配成功;
   * 3. 这里就体现了 'y' 与 'g' 修饰符不同的作用;
   * 4. 相同点:
   *    1. 它们的相同点都是全局匹配;
   * 5. 不同点是:
   *    1. 'g' 修饰符是从上一次匹配成功的位置向后寻找, 直到找到匹配项为止, 它不强调是在上一次匹配成功后的第一个位置匹配成功, 只要后面能够匹配上就算成功 。
   *    2. 'y' 修饰符表示第二次匹配时是在上一次匹配成功之后的第一个位置就要匹配成功, 否则就是匹配失败, 也就是剩余的字符串中有可以匹配的, 但是在这个剩余的字符转中的第一个字符没有匹配成功就不会再向下运行 。
   */



  /**
   * 1. 如何判断正则对象是否开启了 '粘连', 即 y 修饰符
   *    1. sticky: 'sticky' 属性, 表示正则对象是否设置了 'y' 修饰符
   *       1. 设置: 返回 true
   *       2. 未设置: 返回 false
   */
  console.log('sticky 属性: ', regexES5.sticky, regexES6.sticky);
  // 打印结果:
  // sticky 属性:  false true
}

3. u 修饰符

{
  /**
   * 1. u: u 修饰符, 含义为 'Unicode 模式'; 可以理解为 'Unicode' 的缩写, 即第一个字符
   *    1. u 修饰符就是在正则处理 Unicode 字符时的特征值
   */

  /**
   * 1. 为什么第一个没有使用  u 修饰符的结果为 true; 第二个使用了 u 修饰符的结果是 false
   *    1. 在没有使用 u 修饰符时, ES5 不支持 4 字节的 UTF-16 编码 (会把 'uD83D' 当做两个字节, 'uDC2A' 当做两个字节); 把 '\uD83D\uDC2A' 这四个字节当做两个字母或者字符;
   *    2. 在使用了 u 修饰符时, ES6 会把 '\uD83D\uDC2A' 这 4 个字节, 当做一个字符;
   *    3. 所以第一个才会成功 true, 第二个不成功 false 。
   *    4. '\uD83D\uDC2A' 是一个 4 字节的 UTF-16 编码
   *
   * 2. ^ <小知识点>: ^n 匹配任何开头为 n 的字符串 。
   */
  console.log('u 修饰符 -- 未使用: ', /^\uD83D/.test('\uD83D\uDC2A'));
  // 打印结果:
  // u 修饰符 -- 未使用:  true

  console.log('u 修饰符 -- 使用: ', /^\uD83D/u.test('\uD83D\uDC2A'));
  // 打印结果:
  // u 修饰符 -- 使用:  false




  /**
   * 1. n{X}<小知识点>:
   *    1. ES5 中 n{X} 量词, 匹配包含 X 个 n 的序列的字符串 。
   *    2. ES6 新增了使用大括号标识 Unicode 字符的表示方法, 这种表示方法在正则表达式中必须加上 u 修饰符才能识别当中的大括号, 否则会被解读为 量词 。
   *
   * 1. 大括号 {} 包起来的内容是作为 Unicode 字符的, 但是不使用 u 修饰符的话, 它是不会被识别的;
   * 2. 当 大括号 {} 中放的是 Unicode 编码的情况下, 一定要加上 u 修饰符, 才能被 JS 解释器正确识别 。
   */
  console.log('未使用 u 修饰符: ', /\u{61}/.test('a'));
  // 打印结果:
  // 未使用 u 修饰符:  false
  console.log('使用 u 修饰符: ', /\u{61}/u.test('a'));
  // 打印结果:
  // 使用 u 修饰符:  true





  // 加上 u 修饰符, 就会修改下面正则表达式的行为
  /**
   * 1. . <小知识点>: . 元字符, 查找单个字符, 除了换行和行结束符 。
   *    1. 对于码点大于 'OxFFFF' 的 Unicode 字符, 点字符 是不能识别, 必须加上 u 修饰符 。
   *
   * 2. n$ <小知识点>: n$ 量词, 匹配任何结尾为 n 的字符串
   *
   * 3. 总结:
   *    1. 当我们使用正则表达式处理的字符串中, 有大于两个字节长度的字符, 一定要使用 u 修饰符 。
   *    2. 修改在 ES5 中的观念: . 元字符 可以匹配任何字符; 它是有条件的, 就是需要小于两个字节长度的字符 (同时还包括 4 个字符是不能处理的: 换行符、回车符、行分隔符、段分隔符, 当我们遇到这四个字符时, 就需要配合 s 修饰符)。
   */
  console.log('Unicode 编码 (ES6 处理字符串模板转义的方法): ', '\u{20BB7}');
  // 打印结果:
  // Unicode 编码 (ES6 处理字符串模板转义的方法):  
  let str2 = ''
  console.log('未使用 u 修饰符 -- . 元字符: ', /^.$/.test(str2));
  // 打印结果:
  // 未使用 u 修饰符 -- . 元字符:  false
  console.log('使用 u 修饰符 -- . 元字符: ', /^.$/u.test(str2));
  // 打印结果:
  // 使用 u 修饰符 -- . 元字符:  true


  console.log('未使用 u 修饰符, 被识别为 ES5 中的量词: ', /{2}/.test(''));
  // 打印结果:
  // 未使用 u 修饰符, 被识别为 ES5 中的量词:  false
  console.log('使用 u 修饰符, 被识别为 ES6 中的 Unicode 字符: ', /{2}/u.test(''));
  // 打印结果:
  // 使用 u 修饰符, 被识别为 ES6 中的 Unicode 字符:  true

}

以上代码执行结果如图所示:

函数执行结果

之前有整理过部分知识点, 现在将整理的相关内容, 验证之后慢慢分享给大家; 这个专题是 "前端ES6基础" 的相关专栏; 不积跬步,无以至千里, 戒焦戒躁 。

如果对大家有所帮助,可以点个关注、点个赞; 文章会持续打磨 。
有什么想要了解的前端知识, 可以评论区留言, 会及时分享所相关内容 。

你可能感兴趣的:(JavaScript ES6 - 正则表达式扩展)