什么是正则表达式 ?
正则表达式是一组由字母和符号组成的特殊文本,它可以用来从文本中找出满足你想要的格式的句子。
一个正则表达式是一种从左到右匹配主体字符串的模式,常使用缩写的术语"regex"或"regexp"。
1. 正则表达式的基本语法
1.1 字符匹配
.
:匹配任意单个字符(除了换行符)。\d
:匹配数字,等价于[0-9]
。\D
:匹配非数字,等价于[^0-9]
。\w
:匹配字母、数字或下划线,等价于[a-zA-Z0-9_]
。\W
:匹配非字母、数字或下划线,等价于[^a-zA-Z0-9_]
。\s
:匹配空白字符,包括空格、制表符和换行符。\S
:匹配非空白字符。
1.2 字符集
[abc]
:匹配a
、b
或c
中的任意一个字符。[^abc]
:匹配除a
、b
、c
之外的任意字符。[a-z]
:匹配小写字母中的任意一个字符。[0-9]
:匹配数字中的任意一个字符。
1.3 量词
*
:匹配前面的字符零次或多次。+
:匹配前面的字符一次或多次。?
:匹配前面的字符零次或一次。{n}
:匹配前面的字符恰好n次。{n,}
:匹配前面的字符至少n次。{n,m}
:匹配前面的字符至少n次,但不超过m次,一个范围。
1.4 边界匹配
^
:匹配字符串的开始位置。$
:匹配字符串的结束位置。\b
:匹配单词边界。\B
:匹配非单词边界。
2. 正则表达式示例
2.1 基本匹配示例
下面是一些Python中使用正则表达式的基本示例。
示例 1:匹配邮箱地址
import re
# 正则表达式
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
# 测试邮箱
emails = ["test@example.com", "invalid-email@", "user123@domain.co.uk"]
for email in emails:
if re.match(pattern, email):
print(f"{email} 是有效的邮箱")
else:
print(f"{email} 不是有效的邮箱")
解读
^
- 表示匹配字符串的开始位置,确保电子邮件地址从这里开始[a-zA-Z0-9._%+-]+
- 匹配电子邮件地址中的用户名部分:
[a-zA-Z0-9._%+-]
:允许的字符集
-
a-zA-Z
:所有大小写字母0-9
:所有数字.
:点号_
:下划线%
:百分号+
:加号-
:减号 / 连字符+
:表示前面的字符集可以出现 1 次或多次
@
- 匹配电子邮件地址中的 @符号,这是邮箱地址的必备元素[a-zA-Z0-9.-]+
- 匹配域名的主部分(如 gmail、yahoo、company 等):
-
-
a-zA-Z0-9.-\]:允许的字符集
-
-
-
- 字母、数字
.
:点号(用于子域名,如mail.yahoo.com)-
:连字符(某些域名中允许)
-
-
+
:表示前面的字符集可以出现 1 次或多次
\.
- 匹配域名中的点号(如.com、.org 中的点),这里用反斜杠转义,因为点在正则中有特殊含义[a-zA-Z]{2,}
- 匹配顶级域名(如 com、org、cn 等):
-
[a-zA-Z]
:只允许字母{2,}
:表示至少需要 2 个字符(如 cn、uk 等)
$
- 表示匹配字符串的结束位置,确保电子邮件地址在这里结束
运行结果
test@example.com 是有效的邮箱
invalid-email@ 不是有效的邮箱
user123@domain.co.uk 是有效的邮箱
2.2 复杂匹配示例
示例 2:匹配手机号码
import re
# 正则表达式
pattern = r'^\+?(\d{1,3})?[-.\s]?(\d{10})$'
# 测试手机号码
phone_numbers = ["+123-4567890123", "4567890123", "12345", "123-456-7890"]
for number in phone_numbers:
if re.match(pattern, number):
print(f"{number} 是有效的手机号码")
else:
print(f"{number} 不是有效的手机号码")
运行结果
+123-4567890123 是有效的手机号码
4567890123 是有效的手机号码
12345 不是有效的手机号码
123-456-7890 不是有效的手机号码
2.3 替换示例
示例 3:替换文本中的特定内容
import re
text = "Hello, my email is test@example.com. Please contact me!"
# 正则表达式
pattern = r'\S+@\S+'
# 替换邮箱为"[邮箱隐藏]"
new_text = re.sub(pattern, "[邮箱隐藏]", text)
print(new_text)
运行结果
Hello, my email is [邮箱隐藏]. Please contact me!
正则表达式是处理字符串和文本数据的强大工具,能够高效地进行匹配、查找和替换等操作。掌握其基本语法和用法,可以帮助您在编程和数据处理时更为轻松。本文通过多个示例展示了正则表达式在Python中的使用,希望对您有所帮助。
3.正则表达式函数
python的re模块还比较简单,包括以下几个方法:
- re.search():查找符合模式的字符,只返回第一个,返回Match对象
- re.match():和search一样,但要求必须从字符串开头匹配
- re.findall():返回所有匹配的字符串列表
- re.finditer():返回一个迭代器,其中包含所有的匹配,也就是Match对象
- re.sub():替换匹配的字符串,返回替换完成的文本
- re.subn():替换匹配的字符串,返回替换完成的文本和替换的次数
- re.split():用匹配表达式的字符串做分隔符分割原字符串
- re.compile():把正则表达式编译成一个对象,方便后面使用
1. re.search(pattern, string, flags=0)
-
作用 :在字符串中搜索匹配的模式,找到第一个匹配后返回一个
Match
对象,如果没有找到匹配,则返回None
。 -
示例
import re
result = re.search(r'\d+', 'hello 123 world')
print(result.group()) # 输出: 123
2. re.match(pattern, string, flags=0)
-
作用 :与
search()
类似,但是它只匹配字符串的开始。如果字符串的开始不符合模式,则返回None
。 -
示例
result = re.match(r'\d+', '123 hello world')
print(result.group()) # 输出: 123
3. re.findall(pattern, string, flags=0)
-
作用:返回字符串中所有与模式匹配的非重叠匹配项的列表。
-
示例
results = re.findall(r'\d+', 'hello 123 world 456')
print(results) # 输出: ['123', '456']
4. re.finditer(pattern, string, flags=0)
-
作用 :返回一个迭代器,产生所有匹配的
Match
对象。 -
示例
for match in re.finditer(r'\d+', 'hello 123 world 456'):
print(match.group()) # 分别输出: 123 和 456
5. re.sub(pattern, repl, string, count=0, flags=0)
-
作用 :用
repl
替换string
中所有匹配pattern
的部分,返回替换后的字符串。count
参数可以指定最大替换次数。 -
示例
new_string = re.sub(r'\d+', 'number', 'hello 123 world 456')
print(new_string) # 输出: hello number world number
6. re.subn(pattern, repl, string, count=0, flags=0)
-
作用 :与
sub()
相同,但是返回一个元组,包含替换后的字符串和替换的次数。 -
示例
new_string, n = re.subn(r'\d+', 'number', 'hello 123 world 456')
print(new_string) # 输出: hello number world number
print(n) # 输出: 2
7. re.split(pattern, string, maxsplit=0, flags=0)
-
作用 :根据模式对字符串进行分割,返回一个列表。
maxsplit
参数可以指定最大分割次数。 -
示例
parts = re.split(r'\s+', 'hello world')
print(parts) # 输出: ['hello', 'world']
8. re.compile(pattern, flags=0)
-
作用:编译正则表达式模式为正则表达式对象,这样可以在后续的操作中复用这个对象,提高效率。
-
示例
pattern = re.compile(r'\d+')
result = pattern.search('hello 123 world')
print(result.group()) # 输出: 123
以上就是关于re
模块中一些常用方法的简介和示例,希望对您有所帮助。如果您有任何具体的问题或需要进一步的帮助,请随时提问!
4.经验之谈
因为没有读懂shenghuo2 师傅的数据安全解题代码,[]
(字符集)和{}
(量词)前后顺序区别
a.本质区别
- []****(字符集) :定义 "允许出现的单个字符范围",只能匹配一个字符 。例如:
[abc]
表示匹配 "a"、"b" 或 "c" 中的任意一个 字符;[0-9]
表示匹配任意一个数字。 - {}****(量词) :定义 "前面元素的出现次数",不能单独使用,必须跟在某个元素(字符、字符集、分组等)后面。例如:
a{2}
表示 "a" 连续出现 2 次;[0-9]{3}
表示任意数字连续出现 3 次。
b. 前后顺序规则--->[字符集]{次数}
**[]**通常在 **{}**前面 ,因为量词({}
)是用来修饰它前面的元素(可以是 []
定义的字符集)的。即:[字符集]{次数}
→ 表示 "字符集中的字符允许出现的次数"。
示例:
[0-9]{3}
:[0-9]
定义了 "单个数字",{3}
修饰这个字符集,表示 "连续 3 个数字"(如 "123")。[a-zA-Z]{2,5}
:[a-zA-Z]
定义了 "单个字母",{2,5}
表示 "2 到 5 个连续字母"(如 "abc"、"xyz12" 不匹配,因为包含数字)。
c. 反例(错误顺序)--->反过来则是拼接
- 正常逻辑:
[]
(定义单个字符范围)在前,{}
(定义该范围的出现次数)在后 →[字符集]{次数}
。 - 核心关系:
{}
是 "修饰符",[]
是 "被修饰的元素",修饰符必须跟在被修饰元素后面。 - 特殊情况:
[]
内部的{}
仅作为普通符号处理,不表示量词。
5.正则表达是积累
100个例子
一、基础字符与文本匹配
- 匹配纯数字
^\d+$
说明:仅包含 0-9 的数字字符串(如 "12345") - 匹配纯字母
^[A-Za-z]+$
说明:仅包含大小写英文字母(如 "Hello") - 匹配字母和数字
^[A-Za-z0-9]+$
说明:仅包含字母和数字(如 "User123") - 匹配字母、数字和下划线
^[A-Za-z0-9_]+$
说明:适用于用户名(如 "my_name123") - 匹配中文字符
^[\u4e00-\u9fa5]+$
说明:仅包含中文字符(如 "你好世界") - 匹配中文、字母、数字
^[\u4e00-\u9fa5A-Za-z0-9]+$
说明:混合中文、字母和数字(如 "产品 V2.0") - 匹配空白字符
\s+
说明:匹配空格、制表符 (\t
)、换行符 (\n
) 等 - 匹配非空白字符
\S+
说明:匹配任何非空白的字符 - 匹配首尾空格
^\s+|\s+$
说明:用于去除字符串前后的空格 - 匹配空字符串
^$
说明:仅匹配空字符串
二、数字相关
- 验证整数(可正可负)
^-?\d+$
说明:匹配 "123"、"-456"、"0" - 验证正整数
^[1-9]\d*$
说明:不包含 0 和负数(如 "1"、"123") - 验证负整数
^-[1-9]\d*$
说明:如 "-1"、"-123" - 验证非负整数(含 0)
^\d+$
说明:"0"、"123" - 验证非正整数(含 0)
^(-\d+|0)$
说明:"0"、"-123" - 验证浮点数(可正可负)
^-?\d+\.\d+$
说明:如 "1.23"、"-4.56" - 验证正浮点数
^[1-9]\d*\.\d+$
说明:如 "1.23"、"100.0" - 验证负浮点数
^-[1-9]\d*\.\d+$
说明:如 "-1.23"、"-100.0" - 验证非负浮点数(含 0)
^\d+(\.\d+)?$
说明:"0"、"1.23"、"100" - 验证最多 2 位小数的数字
^\d+(\.\d{1,2})?$
说明:适用于金额(如 "100"、"99.9"、"123.45") - 匹配百分比(0%-100%)
^(100(\.0{1,2})?|0\.\d{1,2}|[1-9]\d?(\.\d{1,2})?)\%$
说明:如 "50%"、"99.99%"、"100%" - 匹配数字范围(1-100)
^(100|[1-9]\d?)$
说明:仅匹配 1 到 100 之间的整数
三、日期与时间
- 验证日期(YYYY-MM-DD)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
说明:基础格式验证(不包含闰年逻辑) - 验证日期(YYYY/MM/DD)
^\d{4}/(0[1-9]|1[0-2])/(0[1-9]|[12]\d|3[01])$
说明:斜杠分隔的日期格式 - 验证时间(HH:MM:SS)
^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$
说明:24 小时制完整时间 - 验证时间(HH:MM)
^([01]\d|2[0-3]):([0-5]\d)$
说明:简化的时间格式 - 验证 datetime(YYYY-MM-DD HH:MM:SS)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]) ([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$
说明:日期加时间的完整格式
四、网络相关
- 验证邮箱地址
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
说明:标准邮箱格式(如 "user@example.com") - 验证 URL
^https?://[^\s/$.?#].[^\s]*$
说明:匹配 http/https 开头的网址 - 验证 IPv4 地址
^(?:(?: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]?)$
说明:如 "192.168.1.1" - 验证 IPv6 地址
^(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|::)$
说明:简化版 IPv6 匹配 - 提取 URL 中的域名
(?<=://)[^/]+
说明:从 "https://www.example.com/path"提取"www.example.com" - 匹配域名(不含协议)
^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$
说明:如 "example.com"、"sub.domain.co.uk" - 匹配端口号(1-65535)
^(?:[1-9]\d{0,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$
五、身份与联系方式
- 验证手机号码(中国大陆)
^1[3-9]\d{9}$
说明:11 位数字,以 13-19 开头 - 验证固定电话(带区号)
^\d{3,4}-\d{7,8}(-\d{1,4})?$
说明:如 "010-12345678"、"0755-87654321-1234" - 验证身份证号(18 位)
^\d{17}[\dXx]$
说明:17 位数字 + 最后一位(数字或 X/x) - 验证护照号(中国大陆)
^[EeGg]\d{8}$
说明:以 E/e/G/g 开头,后跟 8 位数字 - 验证港澳通行证
^[HMhm]\d{8}$
说明:以 H/h/M/m 开头,后跟 8 位数字 - 验证台湾通行证
^[Tt]\d{8}$
说明:以 T/t 开头,后跟 8 位数字
六、账号与密码
- 验证用户名(4-16 位,字母、数字、下划线)
^[a-zA-Z0-9_]{4,16}$
- 验证密码(8-16 位,字母 + 数字)
^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,16}$
说明:至少包含 1 个字母和 1 个数字 - 验证强密码(8-20 位,含大小写 + 数字 + 特殊符号)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$
- 验证密码(不能包含空格)
^\S+$
说明:密码中不允许有空格 - 匹配包含至少一个大写字母的字符串
^(?=.*[A-Z]).+$
- 匹配包含至少一个小写字母的字符串
^(?=.*[a-z]).+$
- 匹配包含至少一个数字的字符串
^(?=.*\d).+$
七、文档与格式
- 匹配 HTML 标签
<[^>]+>
说明:匹配任意 HTML 标签(如<div>
、<img src="...">
) - 匹配 Markdown 标题
^#{1,6}\s+.+$
说明:匹配 1-6 级 Markdown 标题(如 "## 标题") - 匹配 Markdown 链接
\[([^\]]+)\]\(([^)]+)\)
说明:匹配[文本](链接)
格式 - 匹配 XML 标签
<\/?[\w-]+(?:\s+[\w-]+="[^"]*")*\/?>
- 匹配 JSON 中的键名
"([^"]+)"\s*:
说明:提取 JSON 中的键名(如从"name": "Tom"
提取 "name") - 匹配注释(// 单行注释)
//.*$
说明:匹配 JavaScript/C++ 风格的单行注释 - 匹配多行注释(/ * ... * /)
\/\*[\s\S]*?\*\/
说明:匹配 C 风格的多行注释
八、金融与编码
- 验证银行卡号(16-19 位数字)
^\d{16,19}$
- 验证信用卡号(带可选空格)
^\d{4}\s?\d{4}\s?\d{4}\s?\d{4,5}$
说明:如 "4111 1111 1111 1111" - 验证邮政编码(中国大陆)
^\d{6}$
- 匹配货币格式(人民币)
^(¥|¥)\d{1,3}(,\d{3})*(\.\d{1,2})?$
说明:如 "¥1,000.00"、"¥100" - 匹配货币格式(美元)
^\$\d{1,3}(,\d{3})*(\.\d{1,2})?$
说明:如 "1,000.00"、"100" - 验证 ISBN-10
^\d{9}[\dXx]$
- 验证 ISBN-13
^\d{13}$
- 匹配 Base64 编码
^[A-Za-z0-9+/=]+$
九、字符限制与提取
- 限制字符串长度(n-m 位)
^.{n,m}$
说明:将 n 和 m 替换为数字(如^.{2,10}$
表示 2-10 位) - 匹配以特定字符开头的字符串
^abc.*$
说明:匹配以 "abc" 开头的字符串 - 匹配以特定字符结尾的字符串
^.*xyz$
说明:匹配以 "xyz" 结尾的字符串 - 匹配不包含特定字符的字符串
^[^abc]+$
说明:不包含 a、b、c 中任何一个字符 - 提取字符串中的数字
\d+
说明:从文本中提取所有数字(如从 "价格 199 元" 提取 "199") - 提取字符串中的字母
[A-Za-z]+
- 提取中文姓名(2-4 字)
[\u4e00-\u9fa5]{2,4}
- 匹配连续重复的字符
(.)\1+
说明:如匹配 "aaabbb" 中的 "aaa" 和 "bbb"
十、路径与文件
- 匹配 Windows 文件路径
^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$
说明:如 "C:\Users\file.txt" - 匹配 Linux/Unix 文件路径
^/(?:[^/]+/)*[^/]*$
说明:如 "/home/user/docs/" - 匹配文件名(含扩展名)
^[^/\\:*?"<>|]+\.[^/\\:*?"<>|]+$
说明:如 "document.pdf" - 匹配图片文件(常见格式)
^.+\.(jpg|jpeg|png|gif|bmp|webp)$
说明:不区分大小写可加i
修饰符 - 匹配视频文件(常见格式)
^.+\.(mp4|avi|mov|mkv|flv|wmv)$
- 匹配音频文件(常见格式)
^.+\.(mp3|wav|flac|aac|ogg)$
- 匹配文档文件(常见格式)
^.+\.(txt|doc|docx|pdf|xls|xlsx|ppt|pptx)$
十一、特殊格式
- 验证车牌号(中国大陆)
^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$
- 验证 16 进制颜色值
^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
说明:如 "#fff"、"#ffffff"、"ff0000" - 验证 RGB 颜色值
^rgb\(\s*(0|[1-9]\d?|1\d\d|2[0-4]\d|255)\s*,\s*(0|[1-9]\d?|1\d\d|2[0-4]\d|255)\s*,\s*(0|[1-9]\d?|1\d\d|2[0-4]\d|255)\s*\)$
说明:如 "rgb (255, 0, 0)" - 验证 UUID(v4)
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
- 匹配 MAC 地址
^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$
说明:如 "00:1A:2B:3C:4D:5E"
十二、社交媒体与通讯
- 匹配 QQ 号码(5-13 位,非 0 开头)
^[1-9]\d{4,12}$
- 匹配微信号(6-20 位,字母开头,含字母、数字、下划线、减号)
^[a-zA-Z][a-zA-Z0-9_-]{5,19}$
- 匹配微博账号(4-30 位,字母、数字、下划线)
^[a-zA-Z0-9_]{4,30}$
- 匹配电话号码(国际格式)
^\+[1-9]\d{0,2}[ -]?\d{1,14}$
说明:如 "+1 1234567890"
十三、编程相关
- 匹配变量名(Python)
^[a-zA-Z_][a-zA-Z0-9_]*$
- 匹配函数名(JavaScript)
^[a-zA-Z_$][a-zA-Z0-9_$]*\(
- 匹配 IP: 端口格式
^(?:(?: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]?):(?:[1-9]\d{0,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$
- 匹配 SQL 中的表名
^[a-zA-Z_][a-zA-Z0-9_]{0,63}$
十四、其他常用场景
- 匹配中文标点符号
[\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b]
说明:。;,:""()、?《》 - 匹配英文标点符号
[.!?,.;:(){}[\]'"]
- 匹配 URL 中的查询参数
[?&]([^=]+)=([^&]+)
说明:提取 "key=value" 格式的参数 - 匹配版本号(x.y.z 格式)
^\d+\.\d+\.\d+$
说明:如 "1.0.0"、"2.3.4" - 匹配 CSS 类名
\.[a-zA-Z_-][a-zA-Z0-9_-]*
- 匹配 HTML 中的 img 标签 src 属性
<img[^>]+src=["']([^"']+)["']
说明:提取图片链接 - 匹配手机号中间 4 位替换为*(脱敏)
(\d{3})\d{4}(\d{4})
说明:替换为\1****\2
- 匹配身份证号中间 8 位替换为*(脱敏)
(\d{6})\d{8}(\d{4})
说明:替换为\1********\2
- 匹配连续的空白行
\n\s*\n
说明:用于文本格式化时去重空行 - 匹配所有 Emoji(基础范围)
[\u2600-\u27BF\uD83C-\uDBFF\uDC00-\uDFFF]+