前言

本章介绍正则的扩展。有些不常用的知识了解即可。

本章原文链接:正则的扩展

RegExp 构造函数

从 ES6 开始,如果RegExp构造函数第一个参数是一个正则对象,并且第二个标志存在且为标志参数,将不再抛出 TypeError ,将使用这些参数创建一个新的正则表达式。原有的正则表达式修饰符将被忽略

const flag = new RegExp(/[0-9]/ig, 'i').flags; // 原有修饰符卫 ig ,被 i 给替代了
console.log(flag); // i

字符串有关正则表达式

ES6将之前字符串上的四个关于正则表达式的方法全部更改为RegExp的实例方法,所以现在所有与正则表达式有关的方法,全部定义在RegExp对象上。

  • String.prototype.match 调用 RegExp.prototype[Symbol.match]
  • String.prototype.replace 调用 RegExp.prototype[Symbol.replace]
  • String.prototype.search调用 RegExp.prototype[Symbol.search]
  • String.prototype.split调用 RegExp.prototype[Symbol.split]

flags 属性

RegExp.prototype.flags 属性 是ES6新增属性,会返回正则表达式的修饰符。

const SAMPLEREG = /abc/ig;
console.log(SAMPLEREG.flags); // gi

u 修饰符

在ES6中新增了 u修饰符,表示使用Unicode码的模式进行匹配。处理大于\uFFFFUnicode 字符

注意

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

  1. 点字符

对于码点大于0xFFFFUnicode 字符,点字符不能识别,必须加上u修饰符。

  1. **Unicode**** 字符表示法**

新增了使用大括号表示 Unicode 字符,这种表示法在正则表达式中必须加上u修饰符,才能识别当中的大括号,否则会被解读为量词。

  1. 量词

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

  1. 预定义模式

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

  1. i 修饰符

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

  1. 转义

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

unicode 属性

RegExp.prototype.unicode 属性表明正则表达式带有"u" 标志。 unicode 是正则表达式独立实例的只读属性。

const SAMPLEREG = /abc/u;

console.log(SAMPLEREG.flags); // u
console.log(SAMPLEREG.unicode); // true

Unicode 属性类

**Unicode property escapes**

ES2018 引入了一种新的类的写法\p{...}和`P{...},用于解决 JavaScript 没有强有效的方式用匹配出不同文字问题。允许正则表达式匹配符合 Unicode` 某种属性的所有字符。

\p{Unicode属性名=Unicode属性值}
// 对于某些属性,可以只写属性名,或者只写属性值。
\p{Unicode属性值}
\p{Unicode属性名} // \P 为 \p 取反
\P{Unicode属性值}
\P{Unicode属性名}

注意:

这两种类只对 Unicode 有效,所以使用的时候一定要加上u修饰符。

\P{…}\p{…}的反向匹配,即匹配不满足条件的字符。

const SAMPLEREG = /\p{Script=Greek}/u;
SAMPLEREG.test('π'); // true

y 修饰符

y 修饰符的作用

在ES6中新增了 y 修饰符,表示执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。

y修饰符与g修饰符相似,都是全局匹配,后一次匹配从上一次匹配成功的下一个位置开始。

区别是:g修饰符只要剩余位置中存在匹配即可;而y修饰符必须从剩余的第一个位置开始匹配。

// y修饰符与g修饰符的区别
const SAMPLE = 'abcdabcd';
const SAMPLEREG1 = /abcd/g;
const SAMPLEREG2 = /abcda/y; console.log(SAMPLEREG1.test(SAMPLE)); // true
console.log(SAMPLEREG2.test(SAMPLE)); // true
console.log(SAMPLEREG1.test(SAMPLE)); // true
console.log(SAMPLEREG2.test(SAMPLE)); // false

注意

实际上,y修饰符号隐含了头部匹配的标志^

const SAMPLEREGGY = /ab/gy;
const SAMPLEREGY = /ab/y; let sample1 = 'ababcabcd'.replace(SAMPLEREGGY, '-');
let sample2 = 'ababcabcd'.replace(SAMPLEREGY, '-'); // 最后一个ab因为不是出现在下一次匹配的头部,所以不会被替换。
console.log(sample1);
// 只能返回第一个匹配,必须与g修饰符联用,才能返回所有匹配。
console.log(sample2);

sticky 属性

RegExp.prototype.sticky表示是否设置了y修饰符。sticky 是正则表达式对象的只读属性。

const SAMPLEREG = /a/gy;
console.log(SAMPLEREG.sticky); // true

s 修饰符

ES2018 引入s修饰符,使得.可以匹配任意单个字符。包括行终止符(line terminator character)。

行终止符

所谓行终止符,就是该字符表示一行的终结。以下四个字符属于“行终止符”。

  • U+000A 换行符(\n
  • U+000D 回车符(\r
  • U+2028 行分隔符(line separator
  • U+2029 段分隔符(paragraph separator
const SAMPLEREG = /ab.cd/s;
console.log(SAMPLEREG.test('ab\ncd') ); // true

dotAll

上面这种情况被称为**dotAll**模式,即点(dot)代表一切字符。正则表达式还引入了一个**dotAll**属性

dotAll 属性返回一个布尔值,表明是否在正则表达式中一起使用"s"修饰符。dotAll 是一个只读的属性,属于单个正则表达式实例。

    const SAMPLEREG = /ab.cd/s;
const sample = SAMPLEREG.test('ab\ncd');
console.log(SAMPLEREG.flags); // s
console.log(SAMPLEREG.dotAll); // true

后行断言

ES2018 引入后行断言,V8 引擎 4.9 版(Chrome 62)已经支持。

  • 先行断言

    x只有在y前面才匹配,必须写成/x(?=y)/

    比如,只匹配百分号之前的数字,要写成/\d+(?=%)/

  • 先行否定断言

    x只有不在y前面才匹配,必须写成/x(?!y)/

    比如,只匹配不在百分号之前的数字,要写成/\d+(?!%)/

  • 后行断言正好与先行断言相反,

    x只有在y后面才匹配,必须写成/(?<=y)x/

    比如,只匹配美元符号之后的数字,要写成/(?<=\$)\d+/

  • 后行否定断言则与先行否定断言相反,

    x只有不在y后面才匹配,必须写成/(?<!y)x/

    比如,只匹配不在美元符号后面的数字,要写成/(?<!\$)\d+/

后行断言需要先匹配/(?<=y)x/x,然后再回到左边,匹配y的部分。顺序为先右后左

// 先行断言
const sample1 = /\d+(?=%)/.exec('100% of US presidents have been male');
// 先行否定断言
const sample2 = /\d+(?!%)/.exec('that’s all 44 of them');
console.log(sample1); // 100
console.log(sample2); // 44 // 后行断言
const sample3 = /(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill');
// 后行否定断言
const sample4 = /(?<!\$)\d+/.exec('it’s is worth about €90');
console.log(sample3); // 100
console.log(sample4); // 90

组匹配

正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容。

ES2018 引入了具名组匹配(Named Capture Groups),允许为每一个组匹配指定一个名字,既便于阅读代码,又便于引用。

具名组匹配在圆括号内部,模式的头部添加“问号 + 尖括号 + 组名”(?<year>),然后就可以在exec方法返回结果的groups属性上引用该组名。同时,数字序号依然有效。

const sampleUsers = `
姓刘名备字玄德
姓关名羽字云长
姓张名飞字翼德`;
const SAMPLEREG = /姓(?<surnames>.+)名(?<name>.+)字(?<word>.+)/g;
let result = SAMPLEREG.exec(sampleUsers); do { console.log(`${result.groups.surnames}${result.groups.name}${result.groups.surnames}${result.groups.word}`);
} while ((result = SAMPLEREG.exec(sampleUsers)) !== null); /*
* 刘备刘玄德
* 关羽关云长
* 张飞张翼德
*/

上面的代码中:?<xxx>的作用就是为这个匹配定义一个组名,在匹配的groups属性中可以查看到匹配的组名,这里可以使用解构赋值直接从匹配结果上为变量赋值。

注意 : 如果要在正则表达式内部引用某个具名组匹配,可以使用\k<组名>的写法

matchAll()

ES2020 增加了String.prototype.matchAll()方法,可以一次性取出所有匹配。不过,它返回的是一个遍历器/迭代器(Iterator),而不是数组。

const string = 'sample1sample2sample3';
const regex = /sample/g; for (const match of string.matchAll(regex)) {
console.log(match);
}
// 遍历输出
/*
['sample', index: 0, input: 'sample1sample2sample3', groups: undefined]
['sample', index: 7, input: 'sample1sample2sample3', groups: undefined]
['sample', index: 14, input: 'sample1sample2sample3', groups: undefined]
*/

ES6学习 第五章 正则的扩展的更多相关文章

  1. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  2. Java基础知识二次学习--第五章 数组

    第五章 数组 时间:2017年4月26日15:11:30~2017年4月26日15:15:54 章节:05章_01节  视频长度:09:30 内容:一维数组的内存分析 心得: Java中数组是引用类型 ...

  3. C#高级编程 (第六版) 学习 第五章:数组

    第五章 数组 1,简单数组 声明:int[] myArray; 初始化:myArray = new int[4]; 为数组分配内存. 还可以用如下的方法: int[] myArray = new in ...

  4. C语言学习第五章

    今天要进行一个重要元素数组的学习了.这一章要掌握什么是数组,数组怎么样命名,数组怎么样使用,以及一些常见的错误和需要注意的事项. 一.      数组的基本概念 数组是可以在内存中连续存储多个元素的结 ...

  5. 深度学习框架PyTorch一书的学习-第五章-常用工具模块

    https://github.com/chenyuntc/pytorch-book/blob/v1.0/chapter5-常用工具/chapter5.ipynb 希望大家直接到上面的网址去查看代码,下 ...

  6. ES6学习笔记(七)-对象扩展

    可直接访问有道云笔记分享链接查看es6所有学习笔记 http://note.youdao.com/noteshare?id=b24b739560e864d40ffaab4af790f885

  7. Es6 学习笔记(一)数组扩展

    扩展运算符 ... 1.数组的扩展运算符将一个数组转换成一个逗号分隔的参数序列 console.log(...[1,2,3])   //1,2,3 ['a', 'b',...[1,3]]   //a, ...

  8. Artech的MVC4框架学习——第五章Model的绑定

    第一Model绑定本质就是为目标Action方法生成参数列表的过程,参数数据存在于http请求.请求的 URL .消息报头或主体中. 第二aciton 参数的元数据通过 ParameterDescri ...

  9. ES6学习笔记(四)-数值扩展

    PS: 前段时间转入有道云笔记,体验非常友好,所以笔记一般记录于云笔记中,每隔一段时间,会整理一下, 发在博客上与大家一起分享,交流和学习. 以下:

随机推荐

  1. Spring Boot 如何热加载jar实现动态插件?

    一.背景 动态插件化编程是一件很酷的事情,能实现业务功能的 解耦 便于维护,另外也可以提升 可扩展性 随时可以在不停服务器的情况下扩展功能,也具有非常好的 开放性 除了自己的研发人员可以开发功能之外, ...

  2. Longhorn 云原生容器分布式存储 - 故障排除指南

    内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生容器分布式存储 - 设计架构和概念 Longhorn 云原生容器分布式存储 - ...

  3. Microsoft Porject Online 学习随手记一:环境创建和数据导入

    没有想像的简单,也没那么复杂 Project OL之前是Dynamics 365 Enterprise P1中的一个模块,目前最新版本只能简单创建并且已经没有Enterprise P1选项. 主要流程 ...

  4. 如何接入 K8s 持久化存储?K8s CSI 实现机制浅析

    作者 王成,腾讯云研发工程师,Kubernetes contributor,从事数据库产品容器化.资源管控等工作,关注 Kubernetes.Go.云原生领域. 概述 进入 K8s 的世界,会发现有很 ...

  5. Noip模拟44 2021.8.19

    比较惊人的排行榜 更不用说爆零的人数了,为什么联赛会这么难!!害怕了 还要再努力鸭 T1 Emotional Flutter 考场上没切掉的神仙题 考率如何贪心,我们把黑色的条延长$s$,白色的缩短$ ...

  6. Linux入门必须养成的七大习惯

    对于很多Linux初学者来说,在刚开始使用linux系统时会感到很多的不适.这里为大家整理了自己以前linux入门时别人告诉我的七个习惯.我相信如果你运用了这七个习惯,在你使用Linux时你会感觉更安 ...

  7. [CSP-S2021] 廊桥分配

    链接: P7913 题意: 有 \(m_1\) 架飞机和 \(m_2\) 架飞机停在两个机场,每架飞机有到达和离开的时间,要将 \(n\) 个廊桥分给两个机场,每个廊桥同一时刻只能停一架飞机,需要最大 ...

  8. Spring:面向切面编程的AOP

    一.前言 除了依赖注入(DI),Spring框架提供的另一个核心功能是对面向方面的编程(AOP)的支持. AOP通常被称为实现横切关注点的工具.横切关注点一词是指应用程序中的逻辑不能与应用程序的其余部 ...

  9. 微软认真聆听了开源 .NET 开发社区的炮轰: 通过CLI 支持 Hot Reload 功能

    微软近日激怒了开源.NET社区,起因是它删除了开源.NET的一项旗舰功能,以提升Visual Studio 的吸引力,尤其是针对与Visual Studio颇有渊源的跨平台源代码编辑器Visual S ...

  10. CPU使用率和平均负载

    转载: https://mp.weixin.qq.com/s?__biz=MzU4NzU0MDIzOQ==&mid=2247487782&idx=3&sn=3f04bb053d ...