正则表达式的使用
JeremyJone ... 2024-6-18 大约 8 分钟
# 正则表达式的使用
# 什么是正则表达式
正则表达式是高级文本匹配模式,用于搜索文本中的指定字符串。其本质是由一些字符和特殊字符组成的字符串,其中的字符可以是字母,数字,特殊字符,可以是零个或多个。这个字符串可以用来搜索文本中的指定字符串。
# 特点
- 方便进行文本搜索和修改
- 它不基于某个语言,并且支持语言众多
- 使用灵活,变化多样
通过正则表达式,可以快速查找、替换、修改特定文本内容。
# 语法
# 元字符
# 匹配字符
定义 | 标识符 | 规则 | 说明 |
---|---|---|---|
普通字符 | abc | 匹配对应的普通字符 | 就是一一对应关系 |
任意单一字符 | . | 匹配除 \n 外的任意一个字符 | 任意匹配一个字符 |
匹配字符集 | [abc] | 匹配中括号中的字符集 | 一个区间可以匹配到多个指定字符。通常该字符集有:[0-9] 、[a-z] 、[A-Z] ,分别对应数字、小写字母、大写字母 |
不匹配符号 | [^] | 在字符集前面添加 ^ 表示不匹配区间 | 一个区间不能包含指定字符。通常该字符集有:[^0-9] 、[^_0-9a-zA-Z] ,分别对应非数字、特殊符号(排除普通符号就是特殊符号) |
匹配任意数字 | \d | 匹配任意数字 | 可以匹配任意数字,等价 [0-9] |
匹配任意非数字 | \D | 匹配任意非数字 | 可以匹配任意非数字,等价 [^0-9] |
匹配任意普通字符 | \w | 匹配任意普通字符 | 可以匹配任意普通字符,等价 [a-zA-Z0-9_] |
匹配任意非普通字符 | \W | 匹配任意非普通字符 | 可以匹配任意非普通字符,等价 [^a-zA-Z0-9_] |
匹配任意空白字符 | \s | 匹配任意空白字符 | 可以匹配任意空白字符,等价 [\t\n\r\f\0] |
匹配任意非空白字符 | \S | 匹配任意非空白字符 | 可以匹配任意非空白字符,等价 [^\t\n\r\f\0] |
以某些字符起始 | ^(?=abc).* | ^(?=) 括号中填写匹配的字符 | 以abc起始 |
以某些字符结尾 | (?<=abc)$ | (?<=)$ 括号中填写匹配的字符 | 以abc起始 |
-
连接符在字符集中表示范围,如[a-zA-Z0-9]
表示匹配a
到z
、A
到Z
、0
到9
。
# 不匹配
定义 | 标识符 | 规则 | 说明 |
---|---|---|---|
不匹配某字符集 | [^a] | [^] 中括号中填写不匹配的字符集 | 不匹配字符a |
不以某些字符起始 | ^(?!abc).* | ^(?!) 括号中填写不匹配的字符 | 不以abc起始 |
不以某些字符结尾 | (?<!abc)$ | (?<!)$ 括号中填写不匹配的字符 | 不以abc起始 |
# 特殊字符
定义 | 标识符 | 规则 | 说明 |
---|---|---|---|
或 | | | 同一地方匹配可以匹配多个指定的值 | 与匹配字符集类似,但这里可以匹配更多内容。比如:hello|world ,可以匹配 hello ,也可以匹配到 world ,不再拘泥于一个字符 |
匹配起始 | ^ 或 \A | 用于匹配一个字符串的起始位置 | 通常 ^ 与其他匹配字符同时使用,用来匹配起始内容是否包含指定内容 |
匹配结束 | $ 或 \Z | 用于匹配一个字符串的结束位置 | 通常 $ 与其他匹配字符同时使用,用来匹配结束内容是否包含指定内容 |
匹配边界 | \b | 匹配一个单词的边界(数字、字母、下划线和其他字符的交界处认为是单词边界) | 示例: - \bis\b -> This is a test -> [is] (只匹配到 This 后面的 is)- is\b -> This is a test -> [is, is] (匹配到 This 里面的 is 与 This 后面的 is) |
匹配非边界 | \B | 匹配一个单词的非边界 | 与 \b 正好相反 |
匹配重复0至多次 | * | 匹配前面的字符(集)0-n次 | 示例:glo* -> Green glass globes glow greenly. -> [gl, glo, glo] |
匹配重复1至多次 | + | 匹配前面的字符(集)1-n次 | 示例:gre+ -> Green glass globes glow greenly. -> [gree, gree] |
匹配重复0或1次 | ? | 匹配前面的字符(集)0-1次 | 示例:gr? -> Green glass globes glow greenly. -> [gr, g, g, g, gr] |
匹配指定次数 | {n} | 匹配前面的字符(集)指定n次(n 为一个数值) | 示例:gre{2} -> Green glass globes glow greenly. -> [gree, gree] |
匹配指定范围次数 | {n,m} | 匹配前面的字符(集)指定n-m次(n、m 为一个数值) | 示例:gre{1,2} -> Green glass globes glow greenly. -> [gree, gree] |
# 转义
上面都是正则表达式的原始字符串,如果需要使用正则表达式中的特殊字符,可以使用转义字符来转义。
特殊字符一般都是用 \
来转义。如遇到匹配 ?
、*
、+
、$
等特殊具有意义的字符,都可以通过 \
转义:
?
->\?
*
->\*
+
->\+
$
->\$
其他同理。
对于转义字符 \
,通过 \\
来转义匹配反斜杠。
# 贪婪
贪婪是一种匹配规则,它会匹配尽可能多的内容,比如:a+
,当遇到 aaaaa
的时候,会匹配全部,即:aaaaa
。
如果我们不希望贪婪,而是尽可能少的去匹配(匹配一个甚至0个),使用 ?
来禁用贪婪即可。
如:
规则 | 内容 | 匹配到的值 |
---|---|---|
a+? | aaaaa | [a] |
a{2,4}? | aaaaa | [aa] |
a{2,4} | aaaaa | [aaaaa] |
# 分组
默认情况下,我们只有一个组,就是全部。也可以通过 (...)
来分组,可以获取到匹配的内容。默认返回一个数组,第一项是全部匹配到的内容,后面依次是小括号的添加顺序。比如:
规则 | 内容 | 匹配到的值 |
---|---|---|
(http[s]?)://(\S+) | https://www.jeremyjone.com | [https://www.jeremyjone.com , https , www.jeremyjone.com ] |
- 正则表达式增加子组后对整体匹配没有影响
- 每个正则表达式可以有很多子组,子组由外到内、从左到右排列
- 子组可以改变重复行为,将子组作为一个整体重复
# 修饰符
修饰符用于标记指定额外的匹配策略。它不在表达式内部,而是在表达式外部。
不同语言的修饰符位置写法不太一样。
修饰符 | 含义 | 描述 |
---|---|---|
i | ignore 忽略大小写 | [a-z] -> [a-zA-Z] |
m | multi line 多行模式 | 使用 ^ 与 $ 匹配每一行的起始和结尾 |
s | dotall 匹配包括换行符的所有字符 | 默认 . 无法匹配到 \n 。加上 s 后,. 是可以匹配到 \n 的 |
u | Unicode 模式 | 使用 Unicode 编码,可以匹配中文 |
g | global 全局匹配 | 全局匹配,匹配所有的匹配结果 |
# 常用的正则表达式
非负整数:^\d+$
正整数:^[0-9]*[1-9][0-9]*$
非正整数:^((-\d+)|(0+))$
负整数:^-[0-9]*[1-9][0-9]*$
整数:^-?\d+$
非负浮点数:^\d+(\.\d+)?$
正浮点数 : ^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)$
非正浮点数:^((-\d+\.\d+)?)|(0+(\.0+)?))$
负浮点数:^(-((正浮点数正则式)))$
英文字符串:^[A-Za-z]+$
英文大写串:^[A-Z]+$
英文小写串:^[a-z]+$
英文字符数字串:^[A-Za-z0-9]+$
英数字加下划线串:^\w+$
E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$
或:^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$
邮政编码:^[1-9]\d{5}$
中文:^[\u0391-\uFFE5]+$
电话号码:^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$
手机号码:^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$
双字节字符(包括汉字在内):^\x00-\xff
匹配首尾空格:(^\s*)|(\s*$)(像vbscript那样的trim函数)
匹配HTML标记:<(.*)>.*<\/\1>|<(.*) \/>
匹配空行:\n[\s| ]*\r
提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
提取信息中的邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
提取信息中的图片链接:(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
提取信息中的IP地址:(\d+)\.(\d+)\.(\d+)\.(\d+)
提取信息中的中国手机号码:(86)*0*13\d{9}
提取信息中的中国固定电话号码:(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}
提取信息中的中国电话号码(包括移动和固定电话):(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}
提取信息中的中国邮政编码:[1-9]{1}(\d+){5}
提取信息中的浮点数(即小数):(-?\d*)\.?\d+
提取信息中的任何数字 :(-?\d*)(\.\d+)?
IP:(\d+)\.(\d+)\.(\d+)\.(\d+)
电话区号:/^0\d{2,3}$/
腾讯QQ号:^[1-9]*[1-9][0-9]*$
帐号(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
中文、英文、数字及下划线:^[\u4e00-\u9fa5_a-zA-Z0-9]+$
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内):[^\x00-\xff]
匹配空行的正则表达式:\n[\s| ]*\r
匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/
sql语句:^(select|drop|delete|create|update|insert).*$
匹配首尾空格的正则表达式:(^\s*)|(\s*$)
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94