ES6扩展
1.RegExp 构造函数
- ES5中,RegExp构造函数的参数有两种情况。
var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;
var regex = new RegExp(/xyz/i);
// 等价于
var regex = /xyz/i;
// 不允许,报错
var regex = new RegExp(/xyz/, 'i');
ES6中,支持如上正则写法
new RegExp(/abc/ig, 'i')
// 原有正则对象中的修饰符(flag)ig,将会被第二个参数i覆盖
2.改变字符串正则方法的调用
match()、replace()、search()和split()
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]
3.u 修饰符,用来正确处理大于 \uFFFF的Unicode 字符
(1)点字符:除了换行符以外的任意单个字符,大于 \uFFFF 的 Unicode 字符无法识别
var s = '';
/^.$/.test(s) // false
/^.$/u.test(s) // true
(2) Unicode 字符表示法
\u{61}/.test('a') // false
/\u{61}/u.test('a') // true
/\u{20BB7}/u.test('') // true
(3) 量词:正确识别码点大于 0xFFFF 的 Unicode 字符
/a{2}/.test('aa') // true
/a{2}/u.test('aa') // true
/{2}/.test('') // false
/{2}/u.test('') // true
(4) \S 预定义模式,匹配所有非空白字符;影响同上
/^\S$/.test('') // false
/^\S$/u.test('') // true
function codePointLength (text) {
var result = text.match(/[\s\S]/gu);
return result ? result.length : 0
}
var s = '';
s.length // 4
codePointLength(s) // 2
(5) 与 i 修饰符,识别非规范的字符
/[a-z]/i.test('\u212A') // false
/[a-z]/iu.test('\u212A') // true
4.RegExp.prototype.unicode 属性:表示是否设置了u修饰符
const r1 = /hello/;
const r2 = /hello/u;
r1.unicode // false
r2.unicode // true
- y 修饰符,粘连(sticky)修饰符
y 修饰符与g修饰符类似,也是全局匹配,后一次都从上一次匹配成功的下一个位置开始- g 修饰符:只要剩余位置中存在匹配即可
- y 修饰符: 匹配必须从剩余的第一个位置开始,不满足返回 null
6.RegExp.prototype.sticky 属性:表示是否设置了y修饰符
var r = /hello\d/y;
r.sticky // true
7.RegExp.prototype.flags 属性:会返回正则表达式的修饰符
ES2018扩展
8.s 修饰符:dotAll 模式
- 引入s修饰符,使得.可以匹配任意单个字符
// 匹配的是任意单个字符写法
/foo[^]bar/.test('foo\nbar') // true
// 上面的解决方案不太符合直觉
/foo.bar/s.test('foo\nbar') // true
9.后行断言
...
10.Unicode 属性类
引入了一种新的类的写法\p{...}和\P{...},允许正则表达式匹配符合 Unicode 某种属性的所有字符
语法如下:Unicode 属性类要指定属性名和属性值
\p{UnicodePropertyName=UnicodePropertyValue}
\P{…}是\p{…}的反向匹配,即匹配不满足条件的字符,这两种类只对Unicode字符有效,使用时一定要加上U 修饰符
// 匹配所有数字
const regex = /^\p{Number}+$/u;
regex.test('²³¹¼½¾') // true
regex.test('㉛㉜㉝') // true
regex.test('ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ') // true
11.具名组匹配
正则表达式使用圆括号进行组匹配
const RE_DATE = /(\d{4})-(\d{2})-(\d{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj[1]; // 1999
const month = matchObj[2]; // 12
const day = matchObj[3]; // 31
为了便于阅读与引用,引入了具名匹配
const RE_DATE = /(?\d{4})-(?\d{2})-(?\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}} = /^(?.*):(?.*)$/u.exec('foo:bar');
one // foo
two // bar
替换:字符串替换时,使用$<组名>引用具名组
let re = /(?\d{4})-(?\d{2})-(?\d{2})/u;
'2015-01-02'.replace(re, '$/$/$')
// '02/01/2015'
引用:如果要在正则表达式内部引用某个“具名组匹配”,可以使用\k<组名>、数字引用(\1)的写法
....