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)
正则表达式默认采用贪婪匹配模式。
- 在该模式下意味着会匹配尽可能长的子串。
我们可以使用 ? 将贪婪匹配模式转化为惰性匹配模式。
- 及是尽可能少的匹配字符以满足正则表达式。
结尾啦
如果你耐着性子一路看到了这里,恭喜!来,给自己一个掌声!我们又差不多掌握了一项不错的前端技能,当然,看一遍是远远不够的,我在这里等着你回来呀!




