es6 基础笔记(三)正则的扩展

正则的扩展

1、RegExp构造函数
RegExp构造函数第一个参数是一个正则对象,那么可以使用第二个参数指定修饰符。而且返回的正则表达式会忽略原有的正则表达式的修饰符,只使用新制定的修饰符。
var regex=new RegExp(/abc/ig,‘i’).flags
//“i”
上面代码,又有正则对象的修饰符是ig,它会被第二个参数i覆盖。

2、字符串的正则方法
字符串对象共有4个方法,可以使用正则表达式:match()、replace()、search()、split()。

3、u修饰符
u修饰符,含义为“Unicode模式”,用来正确处理大于\uFFFF的Unicode字符。也就是说,会正确 处理四个字符的UTF-16编码。
/^\uD83D/u.text(’\uD83D\uDC2A’)//false
/^\uD83D/.test(’\uD83D\uDC2a’)//true
上面代码中,\uD83D\uDC2A是一个四个字节的UTF-16编码,代表一个字符。但是,ES5不支持四个字节的UTF-16编码,会将其识别为两个字符,导致第二行代码结果为true。加了u修饰符以后,ES6就会识别其为一个字符,所以第一行代码结果为false。

点字符
点(.)字符在正则表达式中,含义是除了换行符意外的任意单个字符。对于码点大于0xFFFF的Unicode字符,点字符不能识别,必须加上u修饰符。
例:
var s=‘啊’;
/^. / . t e s t ( s ) / / f a l s e / . /.test(s)//false /^. /.test(s)//false/./u.test(s)//true
上面代码表示,如果不添加u修饰符,正则表达式就会认为字符串为两个字符,从而匹配失败。

Unicode字符表示法
ES6新增了使用大括号表示Unicode字符,这种表示法在正则表达式中必须加上u修饰符,才能识别当中的大括号,否则会被解读为量词。
例:
/\u{61}/.test(‘a’)//false
/\u{61}/u.test(‘a’)//true
/\u{20BB7}/u.test(‘啊’)//true
上面代码表示,如果不加u修饰符,正则表达式无法识别\u{61}这种表示法,指挥认为这匹配61个连续的u。

量词
使用u修饰符后,所有量词都会正确识别码点大于0xFFFF的Unicode字符。
/a{2}/.test(‘aa’)//true
/a{2}/u.test(‘aa’)//true
/啊{2}/test(‘啊啊’)//false
/啊{2}/u.test(‘啊啊’)//fase

预定义模式
u修饰符也影响到预定义模式,能否正确识别码点大于0xFFFF的Unicode字符。
/^\SKaTeX parse error: Undefined control sequence: \S at position 22: …('啊')//false /^\̲S̲/u.test(‘𠮷’) // true
上面代码的\S是预定义模式,匹配所有非空白字符。指有加了u修饰符,它才能正确匹配码点大于0xFFFF的Unicode字符。
利用这点,可以有如下代码,正确返回字符串长度的函数。
function codePointLength(text){
var result=text.match(/[\s\S]/gu);
return result ? result.length :0;
}
var s=‘啊啊’;
s.length//4
codePointLength(s)//2

i 修饰符
有些Unicode字符串的编码不同,但是字型很相近,比如\u004B与\u212A都是大写K。
/[a-z]/i.test(’\u212A’)//false
/[a-z]/iu.test(’\u212A’)//true
上面代码中,不加u修饰符,就无法识别非规范的K字符。

转义
没有u修饰符的情况下,正则中没有定义的转义(如逗号的转义,)无效,而在u模式会报错。
/,/ // /,/
/,/u //报错
上面代码中,没有u修饰符时,逗号前面的反斜杠是无效的,加了u修饰符就报错。

RegExp.prototype.unicode属性
正则实力对象新增unicode属性,表示是否设置了u修饰符。
const r1=/hello/;
const r2=/hello/u;
r1.unicode//false
r2.unicode//true

y 修饰符
y:粘连(sticky)修饰符
y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个未知开始。不同的地方,g修饰符只要剩余未知中存在匹配就可以,而y修饰符确保匹配必须从剩余的第一个未知开始,这也就是“粘连”的涵义。
var s=‘aaa_aa_a’;
var r1=/a+/g;
var r2=/a+/y;

r1.exec(s)//[“aaa”]
r2.exec(s) // [“aaa”]

r1.exec(s) // [“aa”]
r2.exec(s) // null
第一次执行两者行为相同,剩余字符串都是_aa_a。由于g修饰符没有未知要求,所以第二次执行会返回结果,而y修饰符要求匹配必须从头部开始,所以返回null。
如果改一下正则表达式,确保每次都能头部陪陪,y修饰符就会返回结果。
var s=‘aaa_aa_a’;
var r=/a+_/y;

r.exec(s) // [“aaa_”]
r.exec(s) // [“aa_”]

lastIndex 属性指定每次搜索的开始位置,g修饰符从这这个位置开始向后搜索,直到发现匹配为止。
y修饰符同样遵守lastIndex属性,但是要求必须在lastIndex指定的位置发现匹配。
例1
const REGEX = /a/g;
// 指定从2号位置(y)开始匹配
REGEX.lastIndex = 2;
// 匹配成功
const match = REGEX.exec(‘xaya’);
// 在3号位置匹配成功
match.index // 3
// 下一次匹配从4号位开始
REGEX.lastIndex // 4
// 4号位开始匹配失败
REGEX.exec(‘xaya’) // null

例2
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

RegExp.prototype.sticky属性
sticky属性,返回是否使用了正则表达式的修饰符。
var r=/hello\d/y;
r.stickey//true

RegExp.prototype.flags属性
flags属性,返回正则表达式的修饰符。
// ES5 的 source 属性
// 返回正则表达式的正文
/abc/ig.source
// “abc”

// ES6 的 flags 属性
// 返回正则表达式的修饰符
/abc/ig.flags
// ‘gi’

s 修饰符:dotAll模式
s修饰符,可以让点(.)符号匹配任意单个字符。
/foo[^]bar/.test(‘foo\nbar’)
// true

dotAll属性,返回正则表达式是否处在dotAll模式。
const re=/foo.bar/s;
//另一种写法
//const re=new RegExp(‘foo.bar’,‘s’);
re.test(‘foo\nbar’) // true
re.dotAll // true
re.flags // ‘s’

后行断言
JavaScript 语言的正则表达式,只支持先行断言,不支持后行断言。ES2018引入了后行断言。

“先行断言”指的是,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”]

Unicode属性类
ES2018引入了一种新的类的写法\p{…}和\P{…},允许正则表达式匹配符合Unicode 某种属性的所有字符。

const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test(‘π’) // true

居民组匹配
正则表达式使用圆括号进行组匹配。
const RE_DATE = /(\d{4})-(\d{2})-(\d{2})/;
上面代码中,正则表达式里面有三组圆括号。使用exec方法,就可以将这三组匹配结果提取出来。

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

解构赋值和替换
let {groups: {one, two}} = /^(?.)😦?.)$/u.exec(‘foo:bar’);
one // foo
two // bar

引用
正则匹配索引
String.prototype.matchAll()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值