正则表达式 都别吵!我是帅的代表!

欢迎你回来再看一遍~~

作为小白的我在学习前端过程中,难免会碰到正则表达式,那么什么什么正则嘞?通俗解释来讲,它是可以用来从文本中找出满足你想要的格式的句子

比如,我想在下面一串数字中找出能被二整除的数:

1
1 2 3 4 5 6 9 7 8 0 

那么,我们可以很清楚的知道了0、2、4、6、8就是的。

再比如,我们想设定一个用户命名的规则,让用户名包含字符、数字、下划线和连字符,以及限制字符的个数,好让名字看起来没那么丑。那么在通常的前端input中,会把value值做字符匹配,但是如果我们用javascript来判断,则需要写相对复杂的代码。

因此,正则表达式(Regular Expression ,下文简称”正则“)就出现了。这里就不在去赘述其起源,感兴趣的话大家可以去点我百度

正则格式 帅的标准由我说的算!

我们回到之前那个问题:设定一个用户命名的规则,让用户名包含字符、数字、下划线和连字符限制字符,并且需要限制用户名字符数。利用正则我们可以这样写:

1
^[a-z0-9_-]{3,15}$

其中,^为正则开始符号,在中括号[]里的则表示匹配规则,例如这里表示为小写字母a到z数字0到9以及下划线_和连字符-。在大括号{}里的则表示为字符长度为3到15个。最后$为结束符号,表示正则终止。

上面这一条是基本的正则。它可以接受 john_doejo-hn_doejohn12_as。但不匹配Jo,因为它包含了大写的字母,而且太短了。

正则元字符 帅到五官朝我看!

是的,正如四则运算中的加、减、乘、除。正则也有一套自己的运算符,我们可以叫他元字符。元字符不代表他们本身的字面意思,他们都有特殊的含义。一些元字符写在方括号中的时候有一些特殊的意思。常用的一些元字符有这些:

元字符 描述
. 句号匹配任意单个字符,除了换行符。
[ ] 字符种类。匹配方括号内的任意字符。
[^ ] 否定的字符种类。匹配除了方括号里的任意字符。
* 匹配>=0个重复的在*号之前的字符。
+ 匹配>=1个重复的在+号之前的字符。
? 标记在?之前的字符为可选字符。
{n,m} 匹配num个大括号之前的字符或字符集 ,这里(n <=num<= m)。
(xyz) 字符集,匹配与 xyz 完全相等的字符串。
&#124; 或运算符,匹配该符号前或后的字符。
&#92; 转义字符,用于匹配一些保留的字符 [ ] ( ) { } . * + ? ^ $ \ |
^ 从开始行开始匹配。
$ 从末端开始匹配。

为了更好的使用这些元字符,我们一起来来分析分析帅帅的五官😀

.字符

.是元字符中最简单的例子。.匹配任意单个字符,但不匹配换行符。例如,表达式.ar匹配一个任意字符,它后面跟着是ar的字符串。 点击我进行在线练习

正则表达式

.ar

匹配的字符

The car parked in the garage.

[ ]字符集

字符集也叫做字符类。方括号用来指定一个字符集。在方括号中使用连字符来指定字符集的范围。在方括号中的字符集则不关心顺序。例如,表达式[Tt]he 匹配 theThe,这里包含了T的大写和小写。点我进行在线练习

正则表达式

[Tt]he

匹配的字符

The car parked in the garage.

在方括号中,它的句号就表示句号。例如表达式 ar[.] 匹配 ar.字符串。点我进行在线练习

正则表达式

ar[.]

匹配的字符

A garage is a good place to park a car.

否定字符集

一般来说 ^ 表示一个字符串的开头,但它在方括号里头的开头时,表示这个字符集是否定的。例如,表达式[^c]ar 匹配除了c,后面跟着ar的任意字符。点我进行在线练习

正则表达式

[^c]ar

匹配的字符

The car parked in the garage. or cprdarg

*

我们可以凭借着大学里稍微学过的一点东西,知道*为通配符,可以匹配一些数值。梅花号(我比较喜欢这样叫)能够匹配在其之前的字符,这些字符要求出现次数大于或等于0。例如,表达式 a* 匹配0或更多个以a开头的字符。表达式[a-z]* 匹配一个行中所有以小写字母开头的字符串。点我进行在线练习

正则表达式

[a-z]*

匹配的字符

The car parked in the garage #21.

+

在正则中,+*其实差不太多,梅花是包含0次的,而加号则至少需要出现一次。例如表达式c.+t ,它匹配以首字母c开头以t结尾,并且中间跟着至少一个字符的字符串。注意,空格也算一个字符。点我进行在线练习

正则表达式

c.+t

匹配的字符

The fat cat sat on the mat.

?

在正则表达式中,元字符 ? 表示标记在该符号前面的字符为可选,即出现 0 或 1 次是可以的。例如,表达式 [T]?he 匹配字符串 heThe点我进行在线练习

正则表达式

[T]?he

匹配的字符

The car is parked in the garage.

{}

在正则表达式中 {} 是一个量词,常用来限定一个或一组字符可以重复出现的次数。例如, 表达式 [0-9]{2,3} 匹配最少 2 位最多 3 位 0~9 的数字。我们在开头的演示格式中也有展示过。

除了这种写法外,还可以省略第二个参数,例如[0-9]{2,} 匹配至少两位 0~9 的数字。

如果逗号也省略掉则表示重复固定的次数。例如,[0-9]{3} 匹配3位数字。

"[0-9]{2,3}" => The number was 9.9997 but we rounded it off to 10.0.

"[0-9]{2,}" => The number was 9.9997 but we rounded it off to 10.0.

"[0-9]{3}" => The number was 9.9997 but we rounded it off to 10.0.

( )特征标群

就类似于四则运算中的小括号,将小括号里的东西看成一个整体。专业术语来讲就是特征标群是一组写在( )中的子模式正则。

例如, 表达式 (ab)* 匹配连续出现 0 或更多个 ab。如果没有使用 ( ) ,那么表达式 ab* 将匹配连续出现 0 或更多个 b

再比如之前说的 {} 是用来表示前面一个字符出现指定次数。但如果在 {} 前加上特征标群 ( ) ,则表示整个标群内的字符重复 N 次。

我们甚至还可以在 () 中用或字符 | 或进行正则匹配。例如,(c|g|p)ar 匹配 cargarpar. 点我在线练习

正则表达式

(c|g|p)ar

匹配的字符

The car is parked in the garage.

|或运算符

如上面所讲,进行逻辑运算的,我们在高中数学上有学习过。例如 (T|t)he|car 匹配 (T|t)hecar点我在线练习

正则表达式

(T|t)he|car

匹配的字符

The car is parked in the garage.

\转义字符

这个就不用多说啦,当需要匹配一些元字符作为字符串而不要它发挥功能时,我们转义它即可。

^

^ 用来检查匹配的字符串是否在所匹配字符串的开头。例如,在 abc 中使用表达式 ^a 会得到结果 a。但如果使用 ^b 将匹配不到任何结果。因为在字符串 abc 中并不是以 b 开头。^(T|t)he 匹配以 Thethe 开头的字符串。点我在线练习

正则表达式

^(T|t)he

匹配的字符

The car is parked in the garage.

$

同理于 ^ 号,$ 号用来匹配字符是否是最后一个。例如,(at\.)$ 匹配以 at. 结尾的字符串。这里就不做练习了,要做的就点上边儿。

正则简字符 帅到四肢朝我看!

emmm,话说这样的标题确实有歧义,但是,欸嘿~你打我呀?

正则提供一些常用的字符集简写,这里做一个表格总汇一下:

简写 说明
. 除换行符外的所有字符
\w 匹配所有字母数字,等同于 [a-zA-Z0-9_]
\W 匹配所有非字母数字,即符号,等同于: [^\w]
\d 匹配数字: [0-9]
\D 匹配非数字: [^\d]
\s 匹配所有空格字符,等同于: [\t\n\f\r\p{Z}]
\S 匹配所有非空格字符: [^\s]
\f 匹配一个换页符
\n 匹配一个换行符
\r 匹配一个回车符
\t 匹配一个制表符
\v 匹配一个垂直制表符
\p 匹配 CR/LF(等同于 \r\n),用来匹配 DOS 行终止符

我们可以在一些匹配的时候,利用这些简字符完成限制。比如说限制空格。

零宽度断言(前后预查)

相信你也会被这些东西搞懵,可能是头一次听说断言这个词语。的确,当你看到这里的时候就进入了正则的难点了,不过没关系,让我们一起来攻破它。

在使用正则表达式时,有时我们需要捕获的内容前后必须是特定内容,但又不捕获这些特定内容的时候,零宽度断言就起到作用了 。 零宽度断言正如它的名字一样,是一种零宽度的匹配,它匹配到的内容不会保存到匹配结果中去,最终匹配结果只是一个位置而已。

我们先来看看有哪些可用的零宽度断言语法:

符号 描述
?= 正先行断言-存在
?! 负先行断言-排除
?<= 正后发断言-存在
?<! 负后发断言-排除

可能看到这里还是有点懵,这个描述写的太难理解了吧?(我当时对这一块花了很久时间去理解)。没关系!我们上代码看看就懂了:

正先行断言 ?=...

正则表达式

ab(?=[A-Z])

匹配的字符

abCE Hello What?

我们知道,(?=[A-Z])为一个整体,它表示匹配到后面必须要为大写字母的字符。?=为一个正断言语法,故此,整个语法的意思为:

  • 我需要匹配ab后面是大写的字符,大写的字符不算进去。

点我进行在线练习

负先行断言 ?!...

和正先行相反,正先行是要符合括号里的格式的,而它是不要匹配到和后面格式相同的。表达式 (T|t)he(?!\sfat) 匹配 Thethe,且其后不跟着 (空格)fat

正则表达式

(T|t)he(?!\sfat)

匹配的字符

The fat cat sat on the mat. ​

点我进行在线练习

正后发断言 ?<=...

正先行是匹配后面,那正后发断言就是匹配前面,专业一点解释为用于筛选所有匹配结果,筛选条件是其前跟随着断言中定义的格式。例如,表达式 (?<=(T|t)he\s)(fat|mat) 匹配 fatmat,且其前跟着 The the。让我们来看一下实例知道了:

正则表达式

(?<=(T|t)he\s)(fat|mat)

匹配的字符

The fat cat sat on the mat.

表达式表示:我需要匹配fat或者mat字符,而且它的前面是The或者the,注意了,这里还有一个空格。

点我进行在线练习

负后发断言 ?<!...

同上,上面是需要匹配到括号里的字符,那么,我们深刻理解整个字,就是不要匹配到啦!

例如,表达式 (?<!(T|t)he\s)(cat) 匹配 cat,则表示其前不跟着 Thethe

正则表达式

(?<!(T|t)he\s)(cat)

匹配的字符

The cat sat on cat.

点我在线练习

好了!到这里恭喜你基本掌握了正则的零宽度断言,接下来我们继续前进!

模式修正符(标志)

当我们匹配完成之后,对一些结果稍微(xuē wēi 这里是带口音的误导,不要学!逃了!)不那么满意,我们可以后期利用这些标志进行修正。常用的几个标志如下:

标志 说明
i 忽略大小写。
g 全局搜索。
m 多行修饰符:锚点元字符 ^ $ 工作范围在每行的起始。

下面就来逐个学习一下。

i 忽略大小写(Case Insensitive)

修饰语 i 用于忽略大小写。例如,表达式 /The/gi 表示在全局搜索 The,在后面的 i 将其条件修改为忽略大小写,则变成搜索 theTheg 表示全局搜索。

正则表达式

/The/gi

匹配的字符

The fat cat sat on the mat.

[点我进行在线练习](https://regex101.com/r/ahfiuh/1)

g 全局搜索 (Global search)

修饰符 g 常用于执行一个全局搜索匹配,即(不仅仅返回第一个匹配的,而是返回全部)。
例如,表达式 /.(at)/g 表示搜索 任意字符(除了换行)+ at,并返回全部结果。

正则表达式

/.(at)/g

匹配的字符

The fat cat sat on the mat.

[点我进行在线练习](https://regex101.com/r/dO1nef/1)

m多行修饰符 (Multiline)

多行修饰符 m 常用于执行一个多行匹配。

像之前介绍的 (^,$) 用于检查格式是否是在待检测字符串的开头或结尾。但我们如果想要它在每行的开头和结尾生效,我们需要用到多行修饰符 m

例如,表达式 /at(.)?$/gm 表示小写字符 a 后跟小写字符 t ,末尾可选除换行符外任意字符。根据 m 修饰符,现在表达式匹配每行的结尾。

正则表达式

/.at(.)?$/gm

匹配的字符

The fat
cat sat
on the mat.

点我进行在线练习

贪婪匹配与惰性匹配 (Greedy vs lazy matching)

正则表达式默认采用贪婪匹配模式。

  • 在该模式下意味着会匹配尽可能长的子串。
正则表达式

/(.*at)/

匹配的字符

The fat cat sat on the mat.

我们可以使用 ? 将贪婪匹配模式转化为惰性匹配模式。

  • 及是尽可能少的匹配字符以满足正则表达式。
正则表达式

/(.*?at)/

匹配的字符

The fat cat sat on the mat.

点我进行在线练习

结尾啦

如果你耐着性子一路看到了这里,恭喜!来,给自己一个掌声!我们又差不多掌握了一项不错的前端技能,当然,看一遍是远远不够的,我在这里等着你回来呀!