往期回顾
「JavaScript 从入门到精通」2.流程控制和错误处理
前置知识:
JS中的正则表达式是用来匹配字符串中指定字符组合的模式。
另外需要记住:正则表达式也是对象。
1.创建正则表达式
- 使用一个正则表达式字面量:
- 使用RegExp对象:
- new RegExp(str[, attr])接收2个参数,str是一个字符串,指定正则表达式匹配规则,attr可选,表示匹配模式,值有g(全局匹配),i(区分大小写的匹配)和m(多行匹配)。
正则表达式的返回值,是一个新的RegExp对象,具有指定的模式和标志。
返回信息介绍:
关于正则表达式的一些方法属性,文章后面介绍,这里先复习定义和使用。
2.使用正则表达式
JS的正则表达式可以被用于:
- RegExp对象的exec和test方法;
- String对象的match、replace、search和split方法。
2.1 RegExp对象方法
- 2.1.1 exec(str)
str: 需要检索的字符串。
若检索成功,返回匹配的数组,否则返回null。
返回信息介绍:
- 2.1.2 test(str)
str:需要检索的字符串。
若匹配成功返回true否则false。
等价于 reg.exec(str) != null。
^str表示匹配以str开头的字符串,这些符号文章后面会介绍。
2.2 String对象方法
- 2.2.1 search
str.search(reg):
str:被检索的源字符串。
reg:可以是需要检索的字符串,也可以是需要检索的RegExp对象,可以添加标志,如i。
若检索成功,返回第一个与RegExp对象匹配的字符串的起始位置,否则返回-1。
- 2.2.2 match
str.match(reg):
str:被检索的源字符串。
reg:可以是需要检索的字符串,也可以是需要检索的RegExp对象,可以添加标志,如i。
若检索成功,返回与reg匹配的所有结果的一个数组,数组的第一项是进行匹配完整的字符串,之后的项是用圆括号捕获的结果,否则返回null。
'see Chapter 3.4.5.1' 是整个匹配。
'Chapter 3.4.5.1' 被'(chapter \d+(\.\d)*)'捕获。
'.1' 是被'(\.\d)'捕获的最后一个值。
'index' 属性(22)是整个匹配从零开始的索引。
'input' 属性是被解析的原始字符串。
- 2.2.3 replace
将字符串中指定字符替换成其他字符,或替换成一个与正则表达式匹配的字符串。
str.replace(sub/reg,val):
- str: 源字符串
- sub: 使用字符串来检索被替换的文本
- reg: 使用RegExp对象来检索来检索被替换的文本
- val: 指定替换文本
- 返回替换成功之后的字符串,不改变源字符串内容。
val可以使用特殊变量名:
- 2.2.4 split
将一个字符串,按照指定符号分割成一个字符串数组。
str.split(sub[, maxlength]):
- str: 源字符串
- sub: 指定的分割符号或正则
- maxlength: 源字符串
2.3 使用情况
- 当我们想要查找一个字符串中的一个匹配是否找到,可以用test或search方法。
- 当我们想要得到匹配的更多信息,我们就需要用到exec或match方法。
3.正则表达式符号介绍
详细的每个符号的用法,可以查阅 W3school JavaScript RegExp 对象
3.1 修饰符
修饰符描述i执行对大小写不敏感的匹配。g执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。m执行多行匹配。
3.2 方括号
用于查找指定返回之内的字符:
.3 元字符
元字符是拥有特殊含义的字符:
3.4 量词
4. 正则表达式拓展(ES6)
4.1 介绍
在ES5中有两种情况。
- 参数是字符串,则第二个参数为正则表达式的修饰符。
- 参数是正则表达式,返回一个原表达式的拷贝,且不能有第二个参数,否则报错。
ES6中使用:
第一个参数是正则对象,第二个是指定修饰符,如果第一个参数已经有修饰符,则会被第二个参数覆盖。
new RegExp(/abc/ig, 'i');
4.2 字符串的正则方法
常用的四种方法:match()、replace()、search()和split()。
4.3 u修饰符
添加u修饰符,是为了处理大于uFFFF的Unicode字符,即正确处理四个字节的UTF-16编码。
/^\uD83D/u.test('\uD83D\uDC2A'); // false /^\uD83D/.test('\uD83D\uDC2A'); // true
由于ES5之前不支持四个字节UTF-16编码,会识别为两个字符,导致第二行输出true,加入u修饰符后ES6就会识别为一个字符,所以输出false。
注意:
加上u修饰符后,会改变下面正则表达式的行为:
- (1)点字符 点字符(.)在正则中表示除了换行符以外的任意单个字符。对于码点大于0xFFFF的Unicode字符,点字符不能识别,必须加上u修饰符。
var a = ""; /^.$/.test(a); // false /^.$/u.test(a); // true
- (2)Unicode字符表示法 使用ES6新增的大括号表示Unicode字符时,必须在表达式添加u修饰符,才能识别大括号。
/\u{61}/.test('a'); // false /\u{61}/u.test('a'); // true /\u{20BB7}/u.test(''); // true
- (3)量词 使用u修饰符后,所有量词都会正确识别码点大于0xFFFF的 Unicode 字符。
/a{2}/.test('aa'); // true /a{2}/u.test('aa'); // true /{2}/.test(''); // false /{2}/u.test(''); // true
- (4)i修饰符 不加u修饰符,就无法识别非规范的K字符。
/[a-z]/i.test('\u212A') // false /[a-z]/iu.test('\u212A') // true
检查是否设置u修饰符: 使用unicode属性。
const a = /hello/; const b = /hello/u; a.unicode // false b.unicode // true
4.4 y修饰符
y修饰符与g修饰符类似,也是全局匹配,后一次匹配都是从上一次匹配成功的下一个位置开始。区别在于,g修饰符只要剩余位置中存在匹配即可,而y修饰符是必须从剩余第一个开始。
lastIndex属性: 指定匹配的开始位置:
返回多个匹配:
一个y修饰符对match方法只能返回第一个匹配,与g修饰符搭配能返回所有匹配。
'a1a2a3'.match(/a\d/y); // ["a1"] 'a1a2a3'.match(/a\d/gy); // ["a1", "a2", "a3"]
检查是否使用y修饰符:
使用sticky属性检查。
const a = /hello\d/y; a.sticky; // true
4.5 flags属性
flags属性返回所有正则表达式的修饰符。
/abc/ig.flags; // 'gi'
5. 正则表达式拓展(ES9)
在正则表达式中,点(.)可以表示任意单个字符,除了两个:用u修饰符解决四个字节的UTF-16字符,另一个是行终止符。
终止符即表示一行的结束,如下四个字符属于“行终止符”:
- U+000A 换行符(\n)
- U+000D 回车符(\r)
- U+2028 行分隔符(line separator)
- U+2029 段分隔符(paragraph separator)
/foo.bar/.test('foo\nbar') // false
上面代码中,因为.不匹配\n,所以正则表达式返回false。
换个醒,可以匹配任意单个字符:
/foo[^]bar/.test('foo\nbar') // true
ES9引入s修饰符,使得.可以匹配任意单个字符:
/foo.bar/s.test('foo\nbar') // true
这被称为dotAll模式,即点(dot)代表一切字符。所以,正则表达式还引入了一个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'
/s修饰符和多行修饰符/m不冲突,两者一起使用的情况下,.匹配所有字符,而^和$匹配每一行的行首和行尾。
公众号:前端自习课