运维人员不仅要熟悉操作系统、服务器、网络等知识,甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作,持续给大家更新运维工作所需要接触到的知识点,希望大家喜欢。
今天我们要讲的是 Regex 正则表达式。
一、简介
正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
1.1. 目的
- 判断给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
- 可以通过正则表达式,从字符串中获取我们想要的特定部分。
1.2. 特点
- 灵活性、逻辑性和功能性非常强;
- 可以迅速地用极简单的方式达到字符串的复杂控制;
- 对于刚接触的人来说,比较晦涩难懂。
由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器EditPlus,大到Microsoft Word、Visual Studio等大型编辑器,都可以使用正则表达式来处理文本内容。
二、元字符
正则表达式主要依赖于元字符。元字符不代表他们本身的字面意思,他们都有特殊的含义。一些元字符写在方括号中的时候有一些特殊的意思。以下是一些元字符的介绍:
字符 | 描述 |
. | 句号匹配任意单个字符除了换行符。要匹配包括 \n 在内的任何字符,请使用像 (.|\n) 的模式。 |
[ ] | 字符种类。匹配方括号内的任意字符。 |
[^ ] | 否定的字符种类。匹配除了方括号里的任意字符 |
* | 匹配 >=0 个重复的在 * 号之前的字符。例如,zo* 能匹配 z 以及 zoo 。* 等价于 {0,}。 |
+ | 匹配 >=1 个重复的 + 号前的字符。例如, zo+ 能匹配 zo 以及 zoo ,但不能匹配 z 。+ 等价于 {1,}。 |
? | 标记 ? 之前的字符为可选。例如,do(es)? 可以匹配 does 或 does 中的 do。? 等价于 {0,1}。 |
| | 或运算符,匹配符号前或后的字符。例如,`z |
\ | 转义字符,用于匹配一些保留的字符 [ ] ( ) { } . * + ? ^ $ \ | |
^ | 从开始行开始匹配。 |
$ | 从末端开始匹配。 |
{n} | n 是一个非负整数。匹配确定的n次。例如, o{2} 不能匹配 Bob 中的 o ,但是能匹配 food 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n次。例如, o{2,}不能匹配 Bob中的 o,但能匹配 foooood中的所有o。 o{1,}等价于 o+。 o{0,}则等价于 o*。 |
{n,m} | m 和 n 均为非负整数,其中 n<=m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 fooooood 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。 |
(xyz) | 字符集,匹配与 xyz 完全相等的字符串. |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如,[abc] 可以匹配 plain 中的 a。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如, [^abc] 可以匹配 plain 中的 p。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,[a-z] 可以匹配 a 到 z 范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,[^a-z] 可以匹配任何不在 a 到 z 范围内的任意字符。 |
2.1. 语法支持情况
命令或环境
|
.
|
[ ]
|
^
|
$
|
\( \)
|
\{ \}
|
?
|
+
|
|
|
( )
|
vi
|
√
|
√
|
√
|
√
|
√
| |||||
Visual C++
|
√
|
√
|
√
|
√
|
√
| |||||
awk
|
√
|
√
|
√
|
√
|
awk是支持该语法的,只是要在命令行加入 --posix or --re-interval参数即可,可见man awk中的interval expression
|
√
|
√
|
√
|
√
| |
sed
|
√
|
√
|
√
|
√
|
√
|
√
| ||||
delphi
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
| |
python
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
java
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
javascript
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
| |
php
|
√
|
√
|
√
|
√
|
√
| |||||
perl
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
| |
C#
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
√
|
三、字符集简写
正则表达式提供一些常用的字符集简写。如下:
简写 | 描述 |
. | 除换行符外的所有字符 |
\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 行终止符 |
\b | 匹配一个单词边界,指单词和空格间的位置。例如,er\b 可以匹配 never 中的 er,但不能匹配 verb 中的 er。 |
\B | 匹配非单词边界。er\B 能匹配 verb 中的 er,但不能匹配 never 中的 er。 |
四、零宽度断言
符号 | 描述 |
?= | 正先行断言-存在 |
?! | 负先行断言-排除 |
?<= | 正后发断言-存在 |
?<! | 负后发断言-排除 |
五、模式修正符
模式修正符,用来修改表达式的搜索结果。这些标志可以任意的组合使用,它也是整个正则表达式的一部分。
模式修正符 | 描述 |
i | 忽略大小写。 |
g | 全局搜索。 |
m | 多行修饰符:锚点元字符 ^ $ 工作范围在每行的起始。 |
六、实例
6.1. 匹配小数点后几位
// 精确到1位小数
^[1-9][0-9]*$|^[1-9][0-9]*\.[0-9]$|^0\.[0-9]$
// 精确到2位小数
^[0-9]+(.[0-9]{2})?$
6.2. 匹配身份证号
^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$
6.3. 匹配护照
^([a-zA-z]|[0-9]){5,17}$
6.4. 匹配港澳居民来往内地通行证
^([A-Z]\d{6,10}(\(\w{1}\))?)$
6.5. 匹配用户名
// 验证数字、字母、_、-,不包含特殊字符,长度 4-16 之间。
^[a-zA-Z0-9_-]{4,16}$
6.6. 匹配微信号
// 微信号正则,6至20位,以字母开头,字母,数字,减号,下划线。
^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$
6.7. 匹配密码强度
// 密码必须是包含大小写字母和数字的组合,长度在 8-12 之间。
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,12}$
// 密码强度正则,最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符。
^.*(?=.{6,})(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$
// 相同字符不能出现3次,至少8个,至多22个字符组成,包含一个小写字母,一个大写字母,和一个数字。
(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*(.)\1{2})^.{8,22}$
6.8. 匹配火车车次
^[GCDZTSPKXLY1-9]\d{1,4}$
6.9. 匹配中文
// 不限制文字长度。
^[\u4e00-\u9fa5]{0,}$
// 验证2到6位汉字
^[\u4e00-\u9fa5]{2,6}$
6.10. 匹配 MAC 地址
^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$
6.11. 匹配手机号码
^((\+?[0-9]{1,4})|(\(\+86\)))?(13[0-9]|14[57]|15[012356789]|17[03678]|18[0-9])\d{8}$
13段:130、131、132、133、134、135、136、137、138、139
14段:145、147
15段:150、151、152、153、155、156、157、158、159
17段:170、176、177、178
18段:180、181、182、183、184、185、186、187、188、189
国际码,如:中国(+86)
6.12. 匹配 IPv4 地址
(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}
^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
6.13. 匹配 IPv6 地址
(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))
6.14. 匹配邮箱地址
^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$
^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$
6.15. 匹配日期
^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$
6.16. 匹配车牌号
// 包含新能源车牌
^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](?:((\d{5}[A-HJK])|([A-HJK][A-HJ-NP-Z0-9][0-9]{4}))|[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳])$
// 不包含新能源车牌
^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]$
6.17. 匹配整数
// 匹配正整数
^\+?\d+$
// 匹配负整数
^-?\d+$
// 匹配整数
^\+?-?\d+$
6.18. 匹配邮编
^[1-9]\d{5}$
6.19. 匹配英文字母
// 大写英文字母
^[A-Z]+$
// 小写英文字母
^[a-z]+$
6.20. 匹配端口号
^((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$
6.21. 匹配时间
// 24 小时制时间格式 HH:mm:ss
^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$
// 12 小时制时间格式 HH:mm:ss
^(?:1[0-2]|0?[1-9]):[0-5]\d:[0-5]\d$
正则表达式在线测试工具:https://regex101.com/