正则表达式概述
正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象。
作用:正则表达式通常①被用来检索、替换那些符合某个模式(规则)的文本
,例如验证表单∶用户在输入框中只能输入符合制定的规则条件的字词,比如用户注册时用户名只能是由数字、字母和下划线构成等。此外,正则表达式还常用于②过滤掉页面内容中的一些敏感词(替换)
,或③从字符串中获取我们想要的特定部分(提取)
等。
特点:灵活性、逻辑性和功能性非常的强,且可以迅速地用极简单的方式达到字符串的复杂控制。
创建正则表达式
因为正则表达式也是对象,所以创建正则表达式的方法有两种:利用RegExp对象
和字面量
。脚本加载后,正则表达式字面量就会被编译。当正则表达式保持不变时,使用此方法可获得更好的性能。在脚本运行的过程中,用构造函数创建的正则表达式也会被编译。如果正则表达式将会改变,或者它将会从用户输入等来源中动态地产生,就需要使用构造函数来创建正则表达式。
//1、利用RegExp对象来创建正则表达式
let regexp = new RegExp(/123/);
console.log(regexp); // /123/
//2、利用字面量"//"来创建正则表达式.使用一个正则表达式字面量,其由包含在斜杠之间的模式组成
let rg = /123/;
console.log(rg); // /123/
正则表达式内的特殊字符(边界符、量词符、预定义类等)
一个正则表达式可以由简单的字符构成,比如/abc/,也可以是简单和特殊字符的组合,比如/ab*c/。其中特殊字符也被称为元字符
,在正则表达式中是具有特殊意义的专用符号,如^、$、+等。
1、边界符
边界符 | 描述 |
---|---|
^ | 表示匹配行首的文本(以谁开始),即匹配输入的开始。 |
$ | 表示匹配行尾的文本(以谁结尾),即匹配输入的结束。 |
注意:如果^和$同时出现,则表示该正则表达式必须是精确匹配。例如:
//表示输入的字符串必须是以123开头且以123结尾的,即输入的字符串是且只能是123
let re = /^123$/; //正则表达式内不管是数字型还是字符串型都不需要加引号
2、量词符
常见的有以下几种:
字符 | 描述 |
---|---|
+ | 匹配前面一个表达式 1 次或者多次。等价于 {1,}。 |
* | 匹配前一个表达式 0 次或多次。等价于 {0,}。 |
? | 匹配前面一个表达式 0 次或者 1 次。等价于 {0,1}。 |
{n} | n 是一个正整数,匹配了前面一个字符刚好出现了 n 次。 |
{n,} | n是一个正整数,匹配前一个字符至少出现了n次。 |
{n,m} | n 和 m 都是整数。匹配前面的字符至少n次,最多m次。如果 n 或者 m 的值是0, 这个值被忽略。(中间不要有空格) |
3、字符类
字符 | 描述 |
---|---|
[ ] | 一个字符集合。匹配方括号中的任意字符,包括转义序列。可以使用破折号(-)来指定一个字符范围。 |
[^xyz] | 一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符。可以使用破折号(-)来指定一个字符范围。任何普通字符在这里都是起作用的。 |
^[xyz]$ | 方括号里的字符只能选择一个(多选一),否则为false。 |
x|y | 匹配‘x’或者‘y’。 |
注意:①/^ab{2}$/匹配abb,/^(ab){2}$/匹配abab(小括号表示优先级);
②^在方括号里面即为取反,在外面则表示边界符;
③/^abc$/匹配以abc开头和结尾的字符串,而/^[abc]$/匹配一个a或者一个b或者一个c(即多选一)。
4、预定义类
字符 | 描述 |
---|---|
\d | 匹配0-9之间的任一数字,相当于[0-9]。 |
\D | 匹配所有0-9以外的字符,相当于[^0-9]。 |
\w | 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]。 |
\W | 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]。 |
\s | 匹配空格(包括换行符、制表符、空格符等),相当于[\t\r\n\v\f]。 |
\S | 匹配非空格的字符,相当于[^\t\r\n\v\f]。 |
. | (小数点)默认匹配除换行符之外的任何单个字符。 |
详细文档可查看:MDN文档—正则表达式
正则表达式的方法
正则表达式可以被用于RegExp
的exec和test方法以及String
的match、replace、search 和split方法。
方法 | 描述 |
---|---|
exec | 一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。 |
test | 一个在字符串中测试是否匹配的RegExp方法(也就是检查字符串是否符合正则表达式要求的规范),它返回 true 或 false。 |
match | 一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。 |
matchAll | 一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。 |
search | 一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。 |
replace | 一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。 |
split | 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的String方法。 |
当你想要知道在一个字符串中的一个匹配是否被找到,你可以使用test
或search
方法;想得到更多的信息(但是比较慢)则可以使用exec
或match
方法。如果你使用exec
或match
方法并且匹配成功了,那么这些方法将返回一个数组并且更新相关的正则表达式对象的属性和预定义的正则表达式对象。如果匹配失败,那么exec方法返回 null(也就是false)。
断言
表示一个匹配在某些条件下发生。断言包含先行断言
、后行断言
和条件表达式
。
方法 | 描述 |
---|---|
x(?=y) | 仅仅当’x’后面跟着’y’才匹配’x’。这种叫做先行断言(正向断言)。 |
(?<=y)x | 仅当’x’前面是’y’才匹配’x’。这种叫做后行断言(反向断言,ES9扩展)。 |
x(?!y) | 仅仅当’x’后面不跟着’y’时匹配’x’,这被称为正向否定查找。 |
(?<!y)x | 仅仅当’x’前面不是’y’时匹配’x’,这被称为反向否定查找。 |
let str = 'Javascript123一生所爱456呜啦啦789!';
//正向断言
let reg = /\d+(?=呜啦啦)/;
console.log(reg.exec(str));
//反向断言
let reg1 = /(?<=呜啦啦)\d+/; //或者直接let reg1 = /\d+/;
console.log(reg1.exec(str));
禁止贪婪
上面已经详述的量词符如+、*、?等分别代表匹配前面一个表达式 1 次或者多次、匹配前一个表达式 0 次或多次、匹配前面一个表达式 0 次或者 1 次。正则表达式在匹配字符串时会自动匹配最多的次数,即贪婪
。为此在表达式之后加上一个问号表示禁止贪婪。
let str = 'javascript';
let reg = /\D+/;
console.log(reg.exec(str));
//禁止贪婪
let reg1 = /\D+?/;
console.log(reg1.exec(str));
命名捕获分组
将提取出的匹配结果命名分组。
let str = '<a href="https://www.baidu.com/">百度</a>';
let reg = /<a href="(.*)">(.*)<\/a>/;
let s = reg.exec(str);
console.log(s);
let reg1 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
let s1 = reg1.exec(str);
console.log(s1);