社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
(给前端大全加星标,提升前端技能)
作者:前端下午茶 公号 / SHERlocked93
在实际做项目过程中会经常遇到需要验证的情况,这时候如果对正则表达式不够了解,就需要经常去网上找,显得low,为了能够自己手写正则,在下花功夫做了一些笔记,并且用这些知识做了一个正则的代码库(链接见文末),方便平时自己使用。
声明:
ES9代表ES2018,如果特性后加了ES9,那么代表是ES2018中新增的特性
感兴趣的同学可以加文末的微信群,一起讨论吧~
正则表达式(Regular Expression) 是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个规则字符串,这个规则字符串用来表达对字符串的一种过滤逻辑。
简单来说就是:按照某种规则去匹配符合条件的字符串。正则表达式的规则是 / pattern /flags
可以使用字面量形式或者new的方式来创建正则表达式
// 使用直接字面量创建 ,推荐使用,性能更好,注意这里pattern不能为空,不然以为是注释
var exp1 = /d/g
// 使用RegExp对象创建
var exp2 = new RegExp('d', 'g');
模式中使用的所有元字符都建议在之前加 转义,正则表达式中的元字符包括:
( [ { ^ $ | ) ? * + . ] }
修饰符表示正则表达式的匹配模式
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配 |
g | 执行全局匹配,查找所有匹配而非在找到第一个匹配后停止 |
m | 执行多行匹配,会改变 ^ 和 $ 的行为 |
u | 可以匹配4字节的unicode编码 |
s (ES9) | dotAll模式, . 可以匹配换行符 |
加了u修饰符,会正确处理大于 uFFFF
的unicode,比如4字节的? uD83DuDC2A
/^uD83D/.test('uD83DuDC2A') // true
/^uD83D/u.test('uD83DuDC2A') // false
默认情况下, .
可以匹配任意字符,除了换行符,且 .
不能匹配Unicode字符,需要使用u选项启用Unicode模式才行。
ES2018引入了dotAll模式,通过s选项可以启用,这样, .
就可以匹配换行符了。
/foo.bar/.test('foonbar'); // false
/foo.bar/s.test('foonbar'); // true
类使用 []
来表达,用于查找某个范围内的字符
表达式 | 描述 |
---|---|
[abc] | 查找方括号之间的任何字符 |
[0-9] | 查找任何从 0 至 9 的数字 |
还有一些预定义类方便我们直接使用:
预定义类 | 等价 | 描述 |
---|---|---|
s | [tnx0Bfr] | 空格 |
S | [^tnx0Bfr] | 非空格 |
d | [0-9] | 数字 |
D | [^0-9] | 非数字 |
w | [a-zA-Z_0-9] | 单词字符 ( 字母、数字、下划线) |
W | [^a-zA-Z_0-9] | 非单词字符 |
. | [^rn] | 任意字符,除了回车与换行外所有字符 |
f | x0c cL | 匹配一个换页符 |
n | x0a cJ | 匹配一个换行符 |
r | x0d cM | 匹配一个回车符 |
t | x09 cI | 匹配一个制表符 |
v | x0b cK | 匹配一个垂直制表符 |
xxx | 查找以八进制数 xxx 规定的字符 | |
xdd | 查找以十六进制数 dd 规定的字符 | |
uxxxx | 查找以十六进制数 xxxx 规定的 Unicode 字符 |
量词表示匹配多少个目标对象,精确匹配长度使用 {}
量词 | 等价 | 描述 |
---|---|---|
n * | {0,} | 匹配零个或多个n |
n + | {1,} | 匹配至少一个 n 的字符串 |
n ? | {0,1} | 匹配零个或一个n |
{n} | 匹配n次 | |
{n,m} | 匹配n到m次 | |
{n,} | 至少匹配n次 |
边界 | 描述 |
---|---|
^ | 以xx开始,在类 [] 中表示非 |
$ | 以xx结束 |
b | 单词边界 |
B | 非单词边界 |
^
匹配字符串开始位置,也就是位置0,如果设置了 RegExp 对象的 Multiline 属性 m
, ^
也匹配 'n' 或 'r' 之后的位置
$
一般匹配字符串结束位置,如果设置了 RegExp 对象的 Multiline 属性 m
, $
也匹配 'n' 或 'r' 之前的位置
b
匹配一个单词边界,也就是指单词和空格间的位置,如 erb
可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er' B
匹配非单词边界。如 erB
能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'
分组使用 ()
,作用是提取相匹配的字符串,使量词作用于分组 比如 hehe{3}
是把 e
匹配了3次而不是单词,如果希望作用于单词,可以使用分组 (hehe){3}
分组中使用 |
可以达到或的效果 比如:T(oo|ii)m
可以匹配 Toom 和 Tiim
`abToomhaTiimmm`.replace(/T(oo|ii)m/g, '-') // ab-ha-mm
使用 ()
后可以使用 $1
- $9
等来匹配
'2018-02-11'.replace(/(d{4})-(d{2})-(d{2})/g, '$2/$3/$1') // 02/11/2018
n
表示后向引用, 1
是指在正则表达式中,从左往右数第1个 ()
中的内容;以此类推, 2
表示第2个 ()
,