正则扩展
// ES6正则表达式形式 以下均等价于const regex = /xyz/i
// 1.参数是字符串
const regex = new RegExp('xyz', 'i')
// 2.参数是正则表达式
const regex = new RegExp(/xyz/i)
const regex = new RegExp(/xyz/, 'i')
console.log(new RegExp(/xyz/g, 'i').flags) // i
// 字符串的正则方法
String.prototype.match()
String.prototype.replace()
String.prototype.search()
String.prototype.split()
// u修饰符, 用来正确处理大于\uFFFF的Unicode字符, 即可以正确处理4个字符的UTF-16编码
// .符号, 加上u修饰符后可以识别码点大于0xFFFF的Unicode字符
/^.$/.test('𠮷') // false
/^.$/u.test('𠮷') // true
// ES6新增的用大括号表示Unicode字符的正则表达式中必须加上u修饰符才能识别大括号,否则解读为量词
/\u{41}/.test('a') // false
/\u{41}/u.test('a') // true
// i修饰符, 识别字型很近的Unicode字符
/[a-z]/ui.test('\u212A') // true
// y修饰符, 即“粘连”(sticky)修饰符, 与g修饰符类似。y修饰符要求必须从头开始匹配, 相当于g和^结合体
// s修饰符, .不能匹配行终止符(换行符、回车符、行分隔符、段分隔符)
/foo.bar/.test('foo\nbar') // false
/foo.bar/s.test('foo\nbar') // true
// exec返回格式
[
matched, // 整个匹配结果
capture1, // 第一个组匹配
capture2, // 第二个组匹配
..., // ...
captureN, // 第N个组匹配
position, // 匹配开始的位置0
S, // 原字符串
groups // 具名组构成的一个对象, 不是具名组匹配没有这个参数
]
// JavaScript正则表达式只支持先行断言和先行否定断言, ES6引入后行断言和后行否定断言
// 先行断言, 指x只有在y前面才匹配/x(?=y)/, 只匹配%前面的数字/\d+(?=%)/
// 先行否定断言, 指x只有不在y前面才匹配/x(?!y)/, 只匹配不在%前面的数字/\d+(?!%)/
/\d+(?=%)/.exec('100% of US presidents have been male') // '100'
/\d+(?!%)/.exec('that\'s all 44 of them') // '44'
// 后行断言, 指x只有在y后面才匹配/(?<=y)x/, 只匹配美元符号之后的数字/(?<=\$)\d+/
// 后行否定断言, 指x只有不在y后面才匹配/(?<!y)x/, 只匹配不在美元符号之后的数字/(?<!\$)\d+/
/(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill') // '100'
/(?<!\$)\d+/.exec('it\'s is worth about €90') // '90'
// 后行断言的实现需要先匹配/(?<=y)x/的x, 然后再回到左边匹配y的部分。\1表示第1个()匹配到的内容复用, 例子中\1等价于(o)匹配到的内容
/(?<=(o)d\1)r/.exec('hodor') // null
/(?<=\1d(o))r/.exec('hodor') // ['r', 'o']
// \p{}和\P{}, 匹配符合Unicode某种属性的所有字符, 使用时一定要加上u修饰符
/^\p{Number}$/u // 匹配所有数字, 包括罗马数字
// 具名组匹配, 正则表达式使用圆括号进行组匹配, 组匹配只能用数字序号引用, 因此匹配含义不容易看出来
// 组匹配形式
/(\d{4})-(\d{2})-(\d{2})/.exec('1999-12-31') // ['1999-12-31', '1999', '12', '31']
// 具名形式
const matchObj = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/.exec('1999-12-31')
const year = matchObj.groups.year // 1999
const month = matchObj.groups.month // 12
const day = matchObj.groups.day // 31
// 引用, 类似于变量调用
// 引用具名组匹配 \k<组名>
/^(?<word>[a-z]+)!\k<word>$/.test('abc!abc')
// 数字引用
/^(?<word>[a-z]+)!\1$/.test('abc!abc')
// 兼用具名组匹配引用和数字引用
/^(?<word>[a-z]+)!\k<word>!\1$/.test('abc!abc!abc')