正则表达式的使用

JeremyJone ... 2023-7-13 大约 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] 表示匹配 azAZ09

# 不匹配

定义 标识符 规则 说明
不匹配某字符集 [^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