⭐ 简介:大家好,我是zy阿二,是一名对知识充满渴望的自由职业者。
☘️ 最近我沉溺于Python的学习中。你所看到的是我的学习笔记。
❤️ 如果对你有帮助,请关注我,让我们共同进步。有不足之处请留言指正!
Q:本文高频字 “匹配”。什么是匹配?
A :在汉语中 abcdefg 统称:字母。 123456 统称:数字。
- 在正则的语言中
- \w 代表所有字母、数字、下划线;即 abcdefg 统称:\w
- \d 代表数字;即 123456 统称:\d
- 当然这样的描述并不严谨。所以请往下阅读
1. 字符类型的表达式
表达式 | 描述 |
---|---|
[abc] | 匹配 [] 中的任一字符。即:匹配 abc 三个字母的字符。 |
[^abc] | ^开头,代表非。即:表示匹配除了 abc 以外的其他任意字符。 |
[a-z] | 范围匹配,即:匹配 abcdefg …xyz,从a-z区间内的所有字符 |
. | 匹配除换行符以外的任何单个字符。 |
\ | 转义符。 如: . 是正则中的表达式,如需让 . 只匹配 . 的时候就需要写 \. |
\w | 匹配所有字母、数字、包括下划线(等价于[A-Za-z0-9_])。 |
\W | 匹配任何非字母数字(等价于[^A-Za-z0-9_])。 |
\d | 数字。匹配任何数字。 |
\D | 非数字。匹配任何非数字字符。 |
\s | 空白。匹配任何空白字符,包括空格、制表符等。 |
\S | 非空白。匹配任何非空白字符。 |
2. 分组、引用的表达式
表达式 | 描述 |
---|---|
(…) | 匹配并返回括号里的表达式对应的内容。 |
(?:…) | 匹配但不返回括号里的内容, |
\1 | 对前面所匹配分组的引用。比如: (a)(b)\1 匹配ababcababc 中的橙色部分。 (a)(b)\1\2 匹配ababcababc 中的橙色部分 |
3. 边界、锚点的表达式
表达式 | 描述 |
---|---|
^ | 匹配开头。如: ^33能匹配 3321 开头的 33,不能配 1233 中的 33。 |
$ | 匹配字符串结尾。如:33$ 能匹配 1233 中的 33,不能匹配 12334 中的 33 |
\b | 边界匹配。如:33\b 能匹配 1233末尾的 33,能匹配 3321 开头的 33, 不能匹配 12334 中的 33 |
\B | 非边界匹配。33\B 如:能匹配 1233 中的33 不能匹配 1233 末尾的 33 不能匹配 3321 开头的 33 |
4. 表示数量的表达式
表达式 | 描述 |
---|---|
? | 匹配0 ~ 1个。 |
+ | 匹配1 ~ 多个。 |
* | 匹配0 ~ 多个。 |
| | 或,并集。 |
{m} | 匹配前m个 |
{m,} | 匹配最少m个 |
{m,n} | 匹配m~n个 |
- 数量的表达式需要字符类型的表达式一起使用
- 例如:在汉语中 1234 称为:数字;加上量词后叫 4个数字,
- 那么在正则对 1234 的表示就是 \d{4}
- 也可以写 [1234]{4}
- 也可以写 [0-9]{4}
- 也可以写 \d* ,这样写并不严谨。
- 也可以写 \d+,这样写并不严谨。
5. 预查断言
表达式 | 描述 |
---|---|
(?=) | 正向预查。比如Hello(?=World)能匹配HelloWorld中的Hello 但不能匹配HelloPig中的Hello |
(?<=) | 反向预查。比如(?<=Hello)World能匹配HelloWorld中的World 但不能匹配ReadWorld中的World。 |
(?!) | 正向否定预查。比如Hello(?!World)不能匹配HelloWorld中的Hello 但能匹配HelloPig中的Hello。 |
(?<!) | 反向否定预查。比如(?<!Hello)World不能匹配HelloWorld中的World 但能匹配ReadWorld中的World。 |
6. 修饰符、特殊标志
表达式 | 描述 |
---|---|
/…/i | 忽略大小写。 |
/…/g | 全局匹配。 |
/…/m | 多行修饰符。用于多行匹配。 |
/…/s | 默认情况下的 . 是匹配除换行符以外的字符,加上 s 修饰符之后, . 将也能匹配换行符 。 |
7 . 总结,浓缩的都是精华
- .*?
- 可以匹配所有长度的字符串,如果字符串有换行就加 \s
- 只要给 .*? 一个开头和一个结尾,就可以匹配所有想要的内容。
8. 实战1.0
用正则表达式来校验 身份证号码。先简单一点。假定身份证是一个17位的数字加最后一位可能是数字或X。
- 当然身份证每一位数字都有意义,并不是这么简单的。我这里只是假定。
- 解题: \d{17}[\dX]
- 可视化解读:
- 连成一句话: 首先匹配到连续的17个数字后,第18位也是数字或 X ,匹配成功。
- 正则表达式生成可视化地址(英文的,上图是我自己PS翻译的)
8. 实战、 2.0
- 第二个题目。 请用正则表达式校验日期。例如:2022-09-13
-
解题: ^[1-3][\d]{3}-(?:1[0-2]|0?[1-9])-(?:0?[1-9]|[1-2]\d|3\d)$
-
可视化上图:
(懒虫附体不翻译了。)-
^[1-3] 开始匹配字符串开头是1、2、3中的一个(
其实只需要匹配1、2就行了,我这个文章也不可能78年后还有人看吧。) -
[\d]{3} 随后跟随连续的3个数字
-
- 再是年和月的分隔符
-
(?:1[0-2]|0?[1-9]) 分叉成2种情况:
- 1 和0、1、2的组合。即:10、11、12 这3个数字。
- 0 和 1、2、3、4、5、6、7、8、9 组合的数字。即:01、02、03、04、05、06、07、08、09。
-
- 再是月和日的分隔符 -
-
(?:0?[1-9]|[1-2]\d|3\d) 最后分叉成4种情况
- 01、02、03、04、05、06、07、08、09 的数字。代表日期的前9天
- 10 到 29 之间的数字,代表每月日期中的天数
- 最后是 30 或 31。
-
$ 收尾
.
-
-
8. 实战 3.0
最后,请问:^(\d{1,4}-(?:1[0-2]|0?[1-9])-(?:0?[1-9]|[1-2]\d|30|31)) ((?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d)$
这个表达式校验的是什么呢?