ECMAScript 6 学习笔记(四):正则的扩展
栏目: JavaScript · 发布时间: 6年前
内容简介:“Unicode 模式”,用来正确处理大于\uFFFF的 Unicode 字符。正则实例对象新增 unicode 属性,表示是否设置了 u 修饰符。“粘连”(sticky)修饰符,y 修饰符的作用与 g 修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g 修饰符只要剩余位置中存在匹配就可,而 y 修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。y 修饰符的设计本意,就是让头部匹配的标志 ^ 在全局匹配中都有效。
u 修饰符
“Unicode 模式”,用来正确处理大于\uFFFF的 Unicode 字符。
/^\uD83D/u.test('\uD83D\uDC2A') // false
/^\uD83D/.test('\uD83D\uDC2A') // true
正则实例对象新增 unicode 属性,表示是否设置了 u 修饰符。
y 修饰符
“粘连”(sticky)修饰符,y 修饰符的作用与 g 修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g 修饰符只要剩余位置中存在匹配就可,而 y 修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。y 修饰符的设计本意,就是让头部匹配的标志 ^ 在全局匹配中都有效。
const REGEX = /a/y;
// 指定从2号位置开始匹配
REGEX.lastIndex = 2;
// 不是粘连,匹配失败
REGEX.exec('xaya') // null
// 指定从3号位置开始匹配
REGEX.lastIndex = 3;
// 3号位置是粘连,匹配成功
const match = REGEX.exec('xaya');
match.index // 3
REGEX.lastIndex // 4
ES6 的正则实例对象多了 sticky 属性,表示是否设置了 y 修饰符。
s 修饰符
ES6 之前,正则中的“.”无法匹配四个字节的 UTF-16 字符与行终止符,因此 ES6 引入了 s 修饰符,也被称为 dotAll 模式,即点(dot)代表一切字符。同时,正则表达式还引入了一个 dotAll 属性,返回一个布尔值,表示该正则表达式是否处在dotAll模式。
/foo.bar/.test('foo\nbar') // false
/foo.bar/s.test('foo\nbar') // true
flag 属性
ES6 为正则表达式新增了 flags 属性,会返回正则表达式的修饰符。
// ES5 的 source 属性,返回正则表达式的正文 /abc/ig.source // "abc" // ES6 的 flags 属性,返回正则表达式的修饰符 /abc/ig.flags // 'gi'
后行断言
JavaScript 语言的正则表达式,只支持先行断言(lookahead)和先行否定断言(negative lookahead),不支持后行断言(lookbehind)和后行否定断言(negative lookbehind)。ES2018 引入后行断言,V8 引擎 4.9 版(Chrome 62)已经支持。
至此,JavaScript 终于完美支持这四种匹配方法:
// 先行断言,匹配匹配项前面的内容
/\d+(?=%)/.exec('100% of US presidents have been male') // ["100"]
/\d+(?!%)/.exec('that’s all 44 of them') // ["44"]
// 后行断言,匹配匹配项后面的内容
/(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill') // ["100"]
/(?<!\$)\d+/.exec('it’s is worth about €90') // ["90"]
与其他正则操作相反,后行断言的匹配方式是“先右后左”,即后行断言是先从左到右扫描,发现匹配以后再回过头,从右到左完成匹配,因此可能会导致不符合预期的行为:
/(?<=(\d+)(\d+))$/.exec('1053') // ["", "1", "053"]
/^(\d+)(\d+)$/.exec('1053') // ["1053", "105", "3"]
Unicode 属性类
ES2018 引入了一种新的类: \p{}
和 \P{}
,允许正则表达式匹配符合 Unicode 某种属性的所有字符。其中 \P{}
是 \p{}
的反向匹配,即匹配不满足条件的字符。需要注意的是,这两种类只对 Unicode 有效,所以使用的时候一定要加上 u 修饰符。
const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test('π') // true
具名组匹配
正则表达式使用圆括号进行组匹配,使用 exec() 就可以将匹配结果提取出来。
const RE_DATE = /(\d{4})-(\d{2})-(\d{2})/;
const matchObj = RE_DATE.exec('2019-12-31');
const year = matchObj[1]; // 2019
const month = matchObj[2]; // 12
const day = matchObj[3]; // 31
为了方便使用,采用具名组匹配,可以为每一个组指定名字
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31
有了具名组匹配以后,可以使用解构赋值直接从匹配结果上为变量赋值。
let {groups: {one, two}} = /^(?<one>.*):(?<two>.*)$/u.exec('foo:bar');
one // foo
two // bar
如果要在正则表达式内部引用某个“具名组匹配”,可以使用\k<组名>的写法。
const RE_TWICE = /^(?<word>[a-z]+)!\k<word>$/;
RE_TWICE.test('abc!abc') // true
RE_TWICE.test('abc!ab') // false
数字引用(\1)依然有效。
const RE_TWICE = /^(?<word>[a-z]+)!\1$/;
RE_TWICE.test('abc!abc') // true
RE_TWICE.test('abc!ab') // false
字符串取得所有匹配
使用 String.prototype.matchAll 方法,可以一次性取出所有匹配。不过,它返回的是一个遍历器(Iterator),而不是数组。
const string = 'test1test2test3';
// g 修饰符加不加都可以
const regex = /t(e)(st(\d?))/g;
for (const match of string.matchAll(regex)) {
console.log(match);
}
// ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"]
// ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"]
// ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]
上面代码中,由于 string.matchAll(regex) 返回的是遍历器,所以可以用 for…of 循环取出。相对于返回数组,返回遍历器的好处在于,如果匹配结果是一个很大的数组,那么遍历器比较节省资源。除此之外,额可以使用 … 运算符和 Array.from 方法将遍历器转为数组。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- ES6入门之正则的扩展
- 带答案面经分享-L1正则&L2正则
- 神经网络中的网络优化和正则化(四):正则化
- 正则表达式 – 如何使用正则表达式进行Erlang模式匹配?
- 正则表达式创建方式的区别及编写简单的正则方式(js学习总结)
- JavaScript正则表达
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Trading and Exchanges
Larry Harris / Oxford University Press, USA / 2002-10-24 / USD 95.00
This book is about trading, the people who trade securities and contracts, the marketplaces where they trade, and the rules that govern it. Readers will learn about investors, brokers, dealers, arbit......一起来看看 《Trading and Exchanges》 这本书的介绍吧!