版权声明:本人文章仅在掘金平台发布,请勿抄袭搬运,转载请注明作者及原文链接 🦉
阅读提示:网页版带有主题和代码高亮,阅读体验更佳 🍉
说两小时就两小时。
开门见山。
本篇文章每个规则都有一个练习题,建议大家在学习规则时在这个正则表达式练习网站上进行练习。
JS 中的正则
创建正则表达式
js 中内置了正则表达式对象 RegExp
,我们要创建一个正则表达式,可以:
// 构造函数 new 创建
const regExp = new RegExp(pattern, modifiers)
// 字面量创建
const regExp = /12345/;
RegExp
接收两个参数,pattern
描述了表达式的模式,modifiers
是修饰符,用于执行区分大小写和全局匹配。
const regExp = new RegExp("\\w+");
const regExp = /\w+/;
构造函数创建时 pattern
是正则字符串,字面量创建时,pattern
是一个类似 /正则规则/
表达式,是放在双斜杠里的。
modifiers
具体是三个值:
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配。 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
m | 执行多行匹配。 |
可以这么使用:
// 两个参数都是字符串形式,修饰符可以多传
const regExp = new RegExp("\\w+", 'i');
const regExp = new RegExp("\\w+", 'g');
const regExp = new RegExp("\\w+", 'm');
const regExp = new RegExp("\\w+", 'igm');
const regExp = /\w+/i;
const regExp = /\w+/g;
const regExp = /\w+/m;
const regExp = /\w+/igm;
一般下,我们使用字面量的方式创建正则。
正则表达式实例上的方法与属性
和其他 js 对象一样,正则实例上也有一些方法给我们调用。
方法 | 描述 |
---|---|
exec | 检索字符串中指定的值。返回找到的值,并确定其位置 |
test | 检索字符串中指定的值。返回 true 或 false |
toString | 返回正则表达式的字符串 |
exec
方法意为捕获,捕获字符串中的某些内容并作为返回值。举个例子,输入 1-10
格式,拿到第一位数、第二位数,for 循环生成这两位数之间所有自然正整数。那想拿到 -
两边的数字,就要利用 exec
方法。
test
方法意为检测,检测一个字符是否符合正则,返回 true
或 false
。一般我们 test
方法会用得比较多。
const regExp1 = new RegExp("12345");
const regExp2 = /12345/;
regExp1.exec('12345')
regExp2.test('12345')
类似数组字符串自带 length
一样,正则实例也自带一些属性。
属性 | 描述 |
---|---|
constructor | 返回一个函数,该函数是一个创建 RegExp 对象的原型 |
global | 判断是否设置了 "g" 修饰符 |
multiline | 判断是否设置了 "m" 修饰符 |
ignoreCase | 判断是否设置了 "i" 修饰符 |
source | 返回正则表达式的匹配模式 |
lastIndex | 用于规定下次匹配的起始位置 |
正则规则语法
切记:正则表达式中不要随意空格,空格也是会被当做字符处理!
在正则表达式中,有三种括号,()
,[]
,{}
,可以说,学会这三种括号,就学会了正则表达式。我们先从 []
说起,()
理解上会难些,我们放在最后讲解。
直接字符匹配
问题:在以下字符串中匹配 2022
字符串。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
2022年 | 2202年 |
2022年10月 | 2202年10月 |
2022年正则学习 | 2202年正则学习 |
正确答案:/2022/
。
规则:直接字符匹配。
字符组:[]
问题:在以下字符串中匹配 Java
和 java
字符串。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
Java | jjva |
java | jvav |
正确答案:/[Jj]ava/
。
规则:[]
字符组。字符组的意思就是一个中括号,匹配 []
里面的任意一个字符即可。在案例中我们的 java
有大写和小写,如果我们直接匹配 /java/
或者 /Java/
都是不够的,但是我们观察到这两个字符仅仅是首字母大写不同而已,那么只要兼容首字母大小写即可。写成 /javaJava/
更是大错特错,因为这是直接字符匹配,匹配的是字符串中包含 javaJava
的字符,与题意不符。
扩展:匹配以下字符中的 Java,java,Jave,jAve。
需要匹配的 | 不能匹配的 |
---|---|
Java | Javv |
java | jana |
jave | javv |
jAve | jAee |
正确答案:/[Jj][Aa]v[ae]/
。
字符组区间:-
问题:匹配以下字符中包含26个英文字母的字符。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
123456789a | 123456789 |
12121332323v | 12121332323 |
6789098765x | 6789098765 |
正确答案:/\d*[a-zA-Z]/
。
规则:区间
。这里的 \d*
你要是不理解可以不管,后面会说。这题其实是规则2的延伸,如果我们要匹配的可选字符非常多,比如26个英文字母,匹配其中任意一个,难道要写 /[abcd...xyz]/
吗?为了简化这种表达,引入 -
在 []
中表达区间的意义。/[a-z]/
表示小写26个英文字母,[A-Z]
则表示大写,且可以连写 [a-zA-Z]
。还可以匹配数字范围:[0-9a-zA-Z]
。
字符组取反:[^]
问题:在以下字符串中匹配不包含小写字母的字符串。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
12345ASDFGHJ | 123456asdf |
WERTGBJN | ghhhiuiio |
1234567 | ddss1234567 |
正确答案:/[^a-z]/
。
规则:[^]
,字符组取反。有时候我们是想要匹配某个字符,但是我们也有想它不匹配的情况。
扩展:匹配 正
后面不包含 则
的字符。
需要匹配的 | 不能匹配的 |
---|---|
正式 | 正则 |
正反 | 正则表达式 |
正确 | 正则匹配 |
答案:/正[^则]/
数量匹配符:{}
问题:匹配以下含有 jjjjj 的字符。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
jjjjjava | java |
jjjjjavaa | jjava |
jjjjjavaaa | jjjava |
jjjjjavaaaa | jjjjava |
正确答案:/j{5}ava{1,4}/
。
规则:{}
。表示数量,例如这个例子,{5}
表示 j
字符的出现5次,{1,4}
表示字符 a
出现的次数区间,在 1-4
之间(包含4)。当然了,如果这个字符出现次数没有上限,可以写成:{1,}
。
量词 {}
的另一种表达:+
,*
问题:匹配以下含有数字的字符。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
123 | java |
12121 | jjava |
1212121 | jjjava |
454664567 | jjjjava |
正确答案:/\d*/
。
规则:+
,表示该字符至少出现一次,等同于 {1,}
;*
表示该字符出现0或无数次,等同于 {0,}
。很多时候这种简写会带来不少便利,例如,配合任意字符 .
可以匹配任意字符任意次数 /.*/
。例如我现在拷贝了一份 HTML,但是其中的 class 选择器我都要删除,我可以匹配出 /class=".*"/
所有的 class 类从而删除它们。
分组符:()
问题:匹配以下特定文件 .jpg,.png,.mp3,.mp4。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
image.jpg | image.jpeg |
image.png | image.img |
music.mp3 | music.mu |
movie.mp4 | movie.mo |
正确答案:/.*\.(jpg|png|mp3|mp4)/
。
规则:()
。规则分组,类似 js 中的 (a + b) * c
,将一组规则划为一个整体。在此题中,将所有可能出现的文件后缀作为一组。另外,|
表示 或
条件,不再单独讲解。
分组符配合 exec 捕获数据
在前面我们讲过,exec
可以捕获数据,所谓捕获数据,可能有点抽象。我们来举个例子:
问题:有一个输入框,用户输入形如 1-10
,2-9
的数字,开发人员需要将 -
左右两侧的数字提取出来,做其他处理。
分组符 ()
的作用就是将这些要捕获的数据标明出来。当然了,如果我们想要 ()
的分组能力,但是又不想捕获数据,可以使用 (?:)
表达式。
转义符:\
问题:匹配下列左侧字符。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
[] | 23456789 |
-[]- | gfhdhfg |
//[]-- | hfjfj5675 |
正确答案:/[\[\]]\-\/]/
。
规则:\
,转义字符。 正如上题所说,-
在 []
中表示区间,那我如果就是要匹配携带 -
的字符呢?这时候就需要 \
,将这些在正则里有特殊含义的字符转换为普通字符。如果要匹配带 \
的字符,就需要 \\
,使用 \
对 \
进行转义。下面代码拆解本题正则:
/** [] 匹配任意一个字符,这是最外层 [] */
/[]/
/** 使用 \ 对 [] 进行转义,\[\] */
/[\[\]]/
/** 使用 \ 对 - 进行转义 */
/[\[\]]\-/
/** 使用 \ 对 / 进行转义 */
/[\[\]]\-\//
字母数字的快捷表达式:\w
,\d
问题:匹配以下仅包含数字和字母的字符。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
12345ASDFGHJ | !@^&*() |
WERTGBJN | )(*&^%%$) |
1234567 | ##$%^&* |
正确答案:/\w/
。
规则:一些快捷方式,例如 \w
,\d
,\W
,\D
...
快捷方式 | 描述 |
---|---|
\w | 与任意单词字符匹配,任意单词字符表示 [A-Z] 、 [a-z] 、[0-9] 、_ |
\W | \w 的取反 |
\d | 任意数字 |
\D | \d 的取反 |
快捷方式有很多,先记住 \w
,\d
这两个常用的即可。
特殊字符:\n
,\t
,\r
,\s
问题:匹配以下含有空格的字符。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
12345 ASDFGHJ | !@^&*() |
WERT GBJN | )(*&^%%$) |
1234 567 | ##$%^&* |
正确答案:/\s/
。
规则:
字符 | 描述 |
---|---|
\s | 空白符 |
\n | 换行 |
\t | 制表符 tab |
\r | 回车符 |
开始和结束:^
,$
问题:匹配以下1开头9结尾的数字。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
1239 | 189898 |
19 | 2878789 |
19787879 | 2675656 |
正确答案:/^1\d*9$/
。
规则:^
,在这里表示以什么字符开头,在 []
的开头表示取反;$
表示以哪个字符结尾。
任意字符:.
规则:.
字符代表匹配任何单个字符,它只能出现在 []
以外。值得注意的是 .
字符只有一个不能匹配的字符,也就是换行符 \n
。
可选字符:?
问题:匹配以下 java,jva。
你的答案://
?
需要匹配的 | 不能匹配的 |
---|---|
java | jav |
jva | jvav |
正确答案:/ja?va/
。
规则:?
,在这里表示该字符可以没有,这里的 a
可有可无。
总结
正则表达式的学习,狭义上说就是对三种括号 ()
,[]
,{}
的学习。学会了这三种括号,也就是入了正则表达式的门。我们前面也补充了一些常用且重要的特殊字符,例如转义符 \
、开始结束符 ^
$
、数字符 \d
、数字字母快捷符 \w
、特殊字符 \n
\t
、量词快捷符 +
*
等。熟记这几种字符,加上几遍练习,即可掌握正则表达式。下面来做一些练习。
练习1
问题:编写一个匹配手机号码的正则。
解析:手机号码是纯数字的,那么我们想到使用 \d
表示数字,手机号码都是1开头的,那么可以配合 ^
使用。手机号码的第二位数,在3到9之间。另外,手机号码固定11位数,这里可以使用 {}
表示数字的出现次数。
答案:/^1[3-9]\d{9}$/
。网络上有些手机号码正则表达式第二位数将6排除在外,这是有问题的。在联通里有 166
的号码段,第二位数就是6。
练习2
问题:编写一个简易版匹配电子邮箱的正则。
解析:以 QQ
邮箱为例,一般长这样:12345678@qq.com
。特点就是 @
和域名 .com
,主要就是四部分:
12345678
:第一部分@
:第二部分qq
:第三部分.com
:第四部分
接下来代码拆解下正则编写过程:
/**
* 名称部分可能是数字、字母、下划线、短横杠,
* 不能是特殊字符,且必须出现至少1次
*/
/^[\w\-]+/
/** @ */
/^[\w\-]+@/
/** 邮箱服务商 */
/^[\w\-]+@[\w\-]+/
/** 域名 */
/^[\w\-]+@[\w\-]+\.[a-zA-Z]{2,5}$/
答案:/^[\w\-]+@[\w\-]+\.[a-zA-Z]{2,5}$/
恭喜大家已经学完了正则表达式,不知道大家看完本篇文章后,是否已经熟练掌握了正则呢?希望大家不要光看不练,不然,看再多文章和视频都掌握不了正则的。