javascript正则表达式
正则表达式 都别吵!我是帅的代表!
欢迎你回来再看一遍~~
作为小白的我在学习前端过程中,难免会碰到正则表达式,那么什么什么正则
嘞?通俗解释来讲,它是可以用来从文本中找出满足你想要的格式的句子
。
比如,我想在下面一串数字中找出能被二整除的数:
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_doe
、jo-hn_doe
、john12_as
。但不匹配Jo
,因为它包含了大写的字母,而且太短了。
正则元字符 帅到五官朝我看!
是的,正如四则运算
中的加、减、乘、除。正则也有一套自己的运算符,我们可以叫他元字符
。元字符不代表他们本身的字面意思,他们都有特殊的含义。一些元字符写在方括号中的时候有一些特殊的意思。常用的一些元字符有这些:
元字符 | 描述 |
---|---|
. | 句号匹配任意单个字符,除了换行符。 |
[ ] | 字符种类。匹配方括号内的任意字符。 |
[^ ] | 否定的字符种类。匹配除了方括号里的任意字符。 |
* | 匹配>=0 个重复的在*号之前的字符。 |
+ | 匹配>=1 个重复的在+号之前的字符。 |
? | 标记在?之前的字符为可选字符。 |
{n,m} | 匹配num 个大括号之前的字符或字符集 ,这里(n <=num <= m)。 |
(xyz) | 字符集,匹配与 xyz 完全相等的字符串。 |
| | 或运算符,匹配该符号前或后的字符。 |
\ | 转义字符,用于匹配一些保留的字符 [ ] ( ) { } . * + ? ^ $ \ | |
^ | 从开始行开始匹配。 |
$ | 从末端开始匹配。 |
为了更好的使用这些元字符
,我们一起来来分析分析帅帅的五官😀。
.
字符
.
是元字符中最简单的例子。.
匹配任意单个字符,但不匹配换行符。例如,表达式.ar
匹配一个任意字符,它后面跟着是a
和r
的字符串。 点击我进行在线练习
[ ]
字符集
字符集也叫做字符类。方括号用来指定一个字符集。在方括号中使用连字符来指定字符集的范围。在方括号中的字符集则不关心顺序。例如,表达式[Tt]he
匹配 the
和 The
,这里包含了T的大写和小写。点我进行在线练习
在方括号中,它的句号就表示句号。例如表达式 ar[.]
匹配 ar.
字符串。点我进行在线练习
否定字符集
一般来说 ^
表示一个字符串的开头,但它在方括号里头的开头时,表示这个字符集是否定的。例如,表达式[^c]ar
匹配除了c
,后面跟着ar
的任意字符。点我进行在线练习
*
号
我们可以凭借着大学里稍微学过的一点东西,知道*
为通配符,可以匹配一些数值。梅花号(我比较喜欢这样叫)能够匹配在其之前的字符,这些字符要求出现次数大于或等于0
。例如,表达式 a*
匹配0或更多个以a开头的字符。表达式[a-z]*
匹配一个行中所有以小写字母开头的字符串。点我进行在线练习
+
号
在正则中,+
和*
其实差不太多,梅花是包含0次的,而加号则至少需要出现一次。例如表达式c.+t
,它匹配以首字母c
开头以t
结尾,并且中间跟着至少一个字符
的字符串。注意,空格也算一个字符。点我进行在线练习
?
号
在正则表达式中,元字符 ?
表示标记在该符号前面的字符为可选,即出现 0 或 1 次
是可以的。例如,表达式 [T]?he
匹配字符串 he
和 The
。点我进行在线练习
{}
号
在正则表达式中 {}
是一个量词,常用来限定一个或一组字符可以重复出现的次数。例如, 表达式 [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
匹配 car
或 gar
或 par
. 点我在线练习
|
或运算符
如上面所讲,进行逻辑运算的,我们在高中数学上有学习过。例如 (T|t)he|car
匹配 (T|t)he
或 car
。点我在线练习
\
转义字符
这个就不用多说啦,当需要匹配一些元字符作为字符串而不要它发挥功能时,我们转义它即可。
^
号
^
用来检查匹配的字符串是否在所匹配字符串的开头。例如,在 abc
中使用表达式 ^a
会得到结果 a
。但如果使用 ^b
将匹配不到任何结果。因为在字符串 abc
中并不是以 b
开头。^(T|t)he
匹配以 The
或 the
开头的字符串。点我在线练习
$
号
同理于 ^
号,$
号用来匹配字符是否是最后一个。例如,(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 行终止符 |
我们可以在一些匹配的时候,利用这些简字符完成限制。比如说限制空格。
零宽度断言(前后预查)
相信你也会被这些东西搞懵,可能是头一次听说断言
这个词语。的确,当你看到这里的时候就进入了正则的难点了,不过没关系,让我们一起来攻破它。
在使用正则表达式时,有时我们需要捕获的内容前后必须是特定内容,但又不捕获这些特定内容的时候,零宽度断言
就起到作用了 。 零宽度断言
正如它的名字一样,是一种零宽度的匹配,它匹配到的内容不会保存到匹配结果中去,最终匹配结果只是一个位置而已。
我们先来看看有哪些可用的零宽度断言语法:
符号 | 描述 |
---|---|
?= | 正先行断言-存在 |
?! | 负先行断言-排除 |
?<= | 正后发断言-存在 |
?<! | 负后发断言-排除 |
可能看到这里还是有点懵,这个描述写的太难理解了吧?(我当时对这一块花了很久时间去理解)。没关系!我们上代码看看就懂了:
正先行断言 ?=...
我们知道,(?=[A-Z])
为一个整体,它表示匹配到后面必须要为大写字母的字符。?=
为一个正断言语法,故此,整个语法的意思为:
- 我需要匹配ab后面是大写的字符,大写的字符不算进去。
负先行断言 ?!...
和正先行相反,正先行是要符合括号里的格式的,而它是不要匹配到和后面格式相同的。表达式 (T|t)he(?!\sfat)
匹配 The
和 the
,且其后不跟着 (空格)fat
。
正后发断言 ?<=...
正先行
是匹配后面,那正后发断言
就是匹配前面,专业一点解释为用于筛选所有匹配结果,筛选条件是其前跟随着断言中定义的格式。例如,表达式 (?<=(T|t)he\s)(fat|mat)
匹配 fat
和 mat
,且其前跟着 The
或 the
。让我们来看一下实例知道了:
表达式表示:我需要匹配fat
或者mat
字符,而且它的前面是The
或者the
,注意了,这里还有一个空格。
负后发断言 ?<!...
同上,上面是需要匹配到括号里的字符,那么,我们深刻理解负
整个字,就是不要匹配到啦!
例如,表达式 (?<!(T|t)he\s)(cat)
匹配 cat
,则表示其前不跟着 The
或 the
。
好了!到这里恭喜你基本掌握了正则的零宽度断言
,接下来我们继续前进!
模式修正符(标志)
当我们匹配完成之后,对一些结果稍微(xuē wēi 这里是带口音的误导,不要学!逃了!)不那么满意,我们可以后期利用这些标志进行修正。常用的几个标志如下:
标志 | 说明 |
---|---|
i | 忽略大小写。 |
g | 全局搜索。 |
m | 多行修饰符:锚点元字符 ^ $ 工作范围在每行的起始。 |
下面就来逐个学习一下。
i
忽略大小写(Case Insensitive)
修饰语 i
用于忽略大小写。例如,表达式 /The/gi
表示在全局搜索 The
,在后面的 i
将其条件修改为忽略大小写,则变成搜索 the
和 The
,g
表示全局搜索。
g
全局搜索 (Global search)
修饰符 g
常用于执行一个全局搜索匹配,即(不仅仅返回第一个匹配的,而是返回全部)。
例如,表达式 /.(at)/g
表示搜索 任意字符(除了换行)+ at
,并返回全部结果。
m
多行修饰符 (Multiline)
多行修饰符 m
常用于执行一个多行匹配。
像之前介绍的 (^,$)
用于检查格式是否是在待检测字符串的开头或结尾。但我们如果想要它在每行的开头和结尾生效,我们需要用到多行修饰符 m
。
例如,表达式 /at(.)?$/gm
表示小写字符 a
后跟小写字符 t
,末尾可选除换行符外任意字符。根据 m
修饰符,现在表达式匹配每行的结尾。
贪婪匹配与惰性匹配 (Greedy vs lazy matching)
正则表达式默认采用贪婪匹配
模式。
- 在该模式下意味着会匹配尽可能长的子串。
我们可以使用 ?
将贪婪匹配模式转化为惰性匹配
模式。
- 及是尽可能少的匹配字符以满足正则表达式。
结尾啦
如果你耐着性子一路看到了这里,恭喜!来,给自己一个掌声!我们又差不多掌握了一项不错的前端技能,当然,看一遍是远远不够的,我在这里等着你回来呀!