记录原因
最近使用nodejs比较多,正则表达式对于匹配一个字符来说是比较重要的模块,但是自己本身对正则的概念也是过了一遍,在回头看正则表后就不认识了,所以我记录下正则的使用方法,并记录写经典的例子。
什么是正则
正则表达式是一组由字母和符号组成的特殊文本,它可以用来从文本中找出满足你想要的格式的句子。
1.元字符
元字符 | 描述 |
---|---|
. | 句号匹配任意单个字符除了换行符 |
[ ] | 字符种类。匹配方括号内的任意字符。 |
[^ ] | 否定的字符种类。匹配除了方括号里的任意字符 |
* | 匹配>=0个重复的在*号之前的字符。 |
+ | 匹配>=1个重复的+号前的字符。 |
? | 标记?之前的字符为可选. |
{n,m} | 匹配num个大括号之前的字符或字符集 (n <= num <= m). |
(xyz) | 字符集,匹配与 xyz 完全相等的字符串. |
| |
或运算符,匹配符号前或后的字符. |
|
转义字符,用于匹配一些保留的字符 [ ] ( ) { } . * + ? ^ $ | |
^ | 从开始行开始匹配. |
$ | 从末端开始匹配. |
1.1 .字符
".ar" => The car parked in the garage.
.字符匹配任何单个字符。
1.2 [ ]字符
"[Tt]he" => The car parked in the garage.
[]方括叫字符集,里面放的参数加上拼的字符作为条件,里面的顺序不影响任何东西,例如,表达式[Tt]he 匹配 the 和 The。
1.3 [^ ]否定字符集
"[^c]ar" => The car parked in the garage.
[^ ]上面的例子,就是除了c意外跟着ar的匹配方式
1.4 重复次数
后面跟着元字符 +,* or ? 的,用来指定匹配子模式的次数。 这些元字符在不同的情况下有着不同的意思。
1.4.1 *号
[a-z]*
=> The car parked in the garage#21.
例子匹配所有小写的字符,*前的字符出现大于等于0次
1.4.2 +号
"c+t" => The fat cat sat on the mat.
例子,是一个也不能匹配上,因为是+前字符出现大于等于1次,但是这里不能出现两个c,所以匹配不上。
1.4.3 ?号
"[T]?he" => The car is parked in the garage.
例子,匹配到The和he,因为?是指前面的T出现一次或者零次。
1.5 {}号
"[0-9]{2,3}" => The number was 9.9997 but we rounded it off to 10.0.
上面的例子是[0-9]这些能匹配的数字,{2,3}指的是最少两个,最多三个字符的匹配。
在正则表达式中 {} 是一个量词,常用来限定一个或一组字符可以重复出现的次数。
1.6 (...) 特征标群和| 或运算符
"(c|g|p)ar" => The car is parked in the garage.
"(c|g|p)ar"指的是匹配car或gar或par这三个,()更像和数学中的()含义是一样的。
"(T|t)he|car" => The car is parked in the garage.
(T|t)he|car 匹配 (T|t)he 或 car
或运算符就表示或,用作判断条件
1.7 转码特殊字符
"(f|c|m)at.?" => The fat cat sat on the mat.
例子含义匹配fat.或fat或cat.或cat或mat.或mat
用于指定 { } [ ] / + * . $ ^ | ?
这些特殊字符
1.8 锚点
在正则表达式中,想要匹配指定开头或结尾的字符串就要使用到锚点。^ 指定开头,$ 指定结尾。
1.8.1 ^号
"^(T|t)he" => The car is parked in the garage.
^是以The或the开头的数据,所以只能匹配到前面的The(指的是全部文档内容)。
1.8.2 $号
"(at.)$" => The fat cat. sat. on the mat.
和^是相反的$,表示末尾是否能匹配上
2.1 简写字符集
正则表达式提供一些常用的字符集简写。如下:
简写 | 描述 |
---|---|
. |
除换行符外的所有字符 |
w | 匹配所有字母数字,等同于 [a-zA-Z0-9_] |
W | 匹配所有非字母数字,即符号,等同于: [^w] |
d | 匹配数字: [0-9] |
D | 匹配非数字: [^d] |
s | 匹配所有空格字符,等同于: [ f p{Z}] |
S | 匹配所有非空格字符: [^s] |
f | 匹配一个换页符 |
匹配一个换行符 | |
匹配一个回车符 | |
匹配一个制表符 | |
v | 匹配一个垂直制表符 |
p | 匹配 CR/LF(等同于 ),用来匹配 DOS 行终止符 |
3.1 零宽度断言(前后预查)
符号 | 描述 |
---|---|
?= | 正先行断言-存在 |
?! | 负先行断言-排除 |
?<= | 正后发断言-存在 |
?<! | 负后发断言-排除 |
先行断言和后发断言都属于非捕获簇(不捕获文本 ,也不针对组合计进行计数)。 先行断言用于判断所匹配的格式是否在另一个确定的格式之前,匹配结果不包含该确定格式(仅作为约束)。
用人话说就是排除使用判断的内容,匹配剩余的内容,上面表格内容里的前后指的针对的字符串。
例子:(?<=$)[0-9.]* =>$0,1,2,3,4,5,6,7,8,9,.
3.1.1 ?=... 正先行断言
?=... 正先行断言,表示第一部分表达式之后必须跟着 ?=...定义的表达式。
"(T|t)he(?=sfat)" => The fat cat sat on the mat.
匹配到The。
理解方式:匹配这个正先断言前的内容,包含不匹配断言。
3.1.2 ?!... 负先行断言
"(T|t)he(?!sfat)" => The fat cat sat on the mat.
表达式 (T|t)he(?!sfat) 匹配 The 和 the,且其后不跟着 (空格)fat。
理解方式:和正先断言相反,不匹配断言前的内容包含不匹配断言。
3.1.2 ?<= ... 正后发断言
"(?<=(T|t)hes)(fat|mat)" => The fat cat sat on the mat.
表达式指的是the 或the 后跟fat或mat
3.1.2 ?<= ... 负后发断言
"(?<!(T|t)hes)(cat)" => The cat sat on cat.
cat前跟的不是the 和The
4.1 标志
标志也叫模式修正符,因为它可以用来修改表达式的搜索结果。 这些标志可以任意的组合使用,它也是整个正则表达式的一部分。
标志 | 描述 |
---|---|
i | 忽略大小写。 |
g | 全局搜索。 |
m | 多行修饰符:锚点元字符 ^ $ 工作范围在每行的起始。 |
4.1.1 忽略大小写 (Case Insensitive)
"/The/gi" => The fat cat sat on the mat.
4.1.2 全局搜索 (Global search)
"/.(at)/g" => The fat cat sat on the mat.
4.1.3 多行修饰符 (Multiline)
"/.at(.)?$/" => The fat
cat sat
on the mat.
"/.at(.)?$/gm" => The fat
cat sat
on the mat.
这个m会匹配每一行的结尾
5.1 贪婪匹配与惰性匹配 (Greedy vs lazy matching)
正则表达式默认采用贪婪匹配模式,在该模式下意味着会匹配尽可能长的子串。我们可以使用 ? 将贪婪匹配模式转化为惰性匹配模式。
"/(.at)/" => The fat cat sat on the mat.
"/(.?at)/" => The fat cat sat on the mat.
6.1 常见的正则分析
6.1.1、数字、26个英文字母或者下划线组成的字符串:^w+$
分析:^表示开头,w是字母数字缩写,+表示大于1个,$表示结束
6.1.2、中文字符的正则表达式:[u4e00-u9fa5]
6.1.3、^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])d{8}$
分析:^(13是13开头,[0-9]零到九,14[5|7]:14开头,5或7,15[0|1|2|3|5|6|7|8|9],18[0|1|2|3|5|6|7|8|9]和前面一样,d{8}匹配数字,至少8位
6.1.4、身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X:(d{15}$)|(d{18}$)|(^d{17}(d|X|x)$)
分析:d{15}$是最少15数字,|(d{18}$)或者18位数字,(^d{17}(d|X|x)$)或者17位数字加上大小x
6.1.5、Email地址:^w+([-+.]w+)@w+([-.]w+).w+([-.]w+)$
分析:^w+是开头随机数大于一个,([-+.]w+)多个-或随机一个加上数字多个,这个组个是大于零的,@w+([-.]w+)是@加上数子-或者任何数在机上数字,.w+([-.]w+)$是和前那一样
6.1.6、日期格式:^d{4}-d{1,2}-d{1,2}
6.1.7、匹配括号外所有的逗号,理解了好久
,+(?=[^)]*((|$))
匹配方式是逗号有大于等于一个,贪婪正向断言,除去,)
,但是有*
所以匹配一个多个,
,所有的逗号都能匹配上,加上后面的(|$
之前的贪婪匹配方式,就可以获取到所有括号外的逗号。
6.1.8、获取文件名称:
let csvFileName = fileName.match(new RegExp('(?<=(?!.*/)).*(?=(.csv)$)', 'g'));
这里是全局匹配,以.csv为结束,加上正先断言,中间使用.*匹配所有字符,这个前面是?!负先断言,而且是非贪婪匹配所以加上/就匹配到最后那个/
之后,我发现能简写成
let csvFileName = fileName.match(new RegExp('(?!.*/).*(?=(.csv)$)', 'g'));