正则的扩展
0、一句话总结
1、构造函数可以通过第二个参数添加正则表达式的修饰符了;
2、添加了关于utf16字符、粘性匹配的正则表达式修饰符;
3、粘性匹配指:用一个正则表达式连续对一个字符串进行匹配,每次匹配的起始位置是上一次的结束位置;
4、可以通过属性查看正则的内容(sticky)和修饰符(flags)了;
1、变更修饰符
1.1、修饰符
目前已有的修饰符有:
修饰符 | 效果 | 备注 |
g | 全局搜索 | 会将所有匹配到到的都显示出来 |
i | 不区分大小写搜索 | 无视大小写 |
m | 多行搜索 | 正常匹配遇见\n等换行符会终止,添加上这个则不会 |
1.2、查看修饰符
ES6中可以查看修饰符,具体方法是
正则表达式.flags
例如:
/\w/g.flags; //g
注:
在ES5中,正则表达式是没有这个属性的,例如在IE11中,以上会返回undefined
1.3、变更修饰符
可以通过重新创建一个正则表达式的实例,并将旧的正则表达式作为第一个参数,新的修饰符作为第二个参数,即可变更修饰符;
var reg = /\w/g;
var newReg = new RegExp(reg, "i");
newReg; //新的正则表达式/\w/i
注意,以上的方法是覆写掉之前的修饰符。如果单纯是添加的话,可以通过flags属性作为第二个参数的一部分,和新的修饰符拼接起来;
2、新的修饰符
2.1、修饰符u
修饰符 | 效果 | 备注 |
u | 匹配Unicode字符 | 对于码点大于\uFFFF的字符,如果不通过这种方式,是无法匹配到的 |
对于码点大于\uFFFF的字符,普通的正则表达式是无法匹配到的,例如’\uD83D\uDC2A’会被认为是2个字符,而不是一个字符(这个字符是一个小马);
而加了修饰符u后,就可以正确的匹配到他了;
/\uD83D/.test('\uD83D\uDC2A'); //true
/\uD83D/u.test('\uD83D\uDC2A'); //false
//括号里的是一个utf8字符(他的码点大于0xFFFF,而不是两个普通的字符)
另外,只有加了修饰符u之后,正则表达式才能正确的匹配到码点比较大的字符,否则会认为大于0xFFFF的字符都是2个字符;
例如各种元字符,各种量词。
不过换句话说,大部分码点大于0xFFFF字符的,都不是中文的常见字符。所以我认为最重要的是通过修饰符u来查看字符串的实际长度。
这里附一个阮一峰写的函数,注释是我自己加上的
//获取字符串的长度,参数是目标字符串
function codePointLength(text) {
//通过全局匹配,可以识别码点过大的字符
var result = text.match(/[\s\S]/gu);
//如果是空字符串,则会返回null,而不是空数组,因此需要判断一下
return result ? result.length : 0;
}
codePointLength('\uD83D\uDC2A'); //1
2.2、修饰符y
修饰符 | 效果 | 备注 |
y | 粘性搜索 | 指若字符串对同一个表达式的多次匹配,会从上一次匹配成功的位置开始 |
简单来说,第一次匹配到字符a,然后下一次就从字符a(但不包括字符a,lastIndex可以理解为当前从哪一个下标开始匹配)开始匹配了(而不是再重头开始匹配)。
var str = 'abcdef';
var reg = /\w/y;
console.log(str.match(reg)); //["a"]
console.log(reg.lastIndex); //1
console.log(str.match(reg)); //["b"]
console.log(reg.lastIndex); //2
2.3、lastIndex和粘性匹配
简单来说,当正则表达式有修饰符g时,可以通过lastIndex属性查看下一次从哪个位置开始匹配;
如以下代码:
var reg = /\w+/g;
var abc = 'abc';
reg.exec(abc);
console.log(reg.lastIndex); //3
但唯一需要注意的是,需要通过exec方法来匹配,而不能通过str.match(reg)这样的方法来获取匹配到的字符串。
另外,如果没有修饰符g,那么是不会生效的;
注意,这个和粘性匹配的过程很类似,只不过粘性匹配无需修饰符g,也并非只能通过exec来获取匹配到的内容。
粘性匹配 | 需要修饰符g | 可以使用reg.exec(str)或str.match(reg) | 可以通过lastIndex查看目前匹配到哪个位置 |
修饰符g的匹配 | 需要修饰符g(必须) | 只能通过reg.exec(str)来匹配,否则lastIndex不会变化 | 可以通过lastIndex查看目前匹配到哪个位置 |
2.4、正则表达式字符.(英文句号)(非ES6新增)
英文句号.在正则表示任意单字符,但是除了行终止符。
行终止符包括:
①换行符\n(换行)
②回车符\r(不知道有啥用,总之不换行)
③行分隔\u2028(不知道有啥用)
④段分隔符\u2029(不知道有啥用+1)
所以无法识别以下字符
/./.test("\n"); //false
/./.test("\r"); //false
/./.test("\u2028"); //false
/./.test("\u2029"); //false
但可以识别其他字符,比如
/./.test("\u2027"); //true
3、正则表达式的属性
3.1、sticky属性
简单来说,就是检测有没有修饰符y,有则返回true,有没则返回false
/a/y.sticky; //true
/a/.sticky; //false
3.2、source属性(es5)
获取正则表达式的正文。
/abc/g.source; //"abc"
3.3、flags属性
获取正则表达式的修饰符。
/abc/g.flags; //"g"
/abc/gy.flags; //"qy"
4、其他
有一些新提案(ES6不支持),这里只简单提一下,关心的可以去看 阮一峰的文章
①修饰符s(dotAll模式):正则表达式的英文句号在加上这个修饰符后,可以对所有单个字符进行匹配;
②后行断言:假如有字符”ab”,只有b在a后面的时候,才符合正则表达式;
后行否定断言:只有b不在a后面的时候,才符合正则表达式
③匹配符合Unicode某种属性的字符:例如只匹配希腊字符,十进制字符,罗马字符等;