一、简介
在 Python 中,正则表达式主要通过 re
模块实现,用于字符串的匹配、查找、替换等操作。
二、Python的re
模块
使用前需要导入:
import re
三、常用方法
方法 | 描述 |
---|---|
re.match(pattern, string) | 从字符串开头匹配,返回第一个匹配对象,否则返回 None |
re.search(pattern, string) | 扫描整个字符串,返回第一个匹配对象,否则返回 None |
re.findall(pattern, string) | 返回所有匹配的子字符串列表 |
re.finditer(pattern, string) | 返回所有匹配的迭代器(包含匹配对象) |
re.sub(pattern, repl, string) | 将匹配的子字符串替换为 repl |
re.split(pattern, string) | 按匹配模式分割字符串,返回列表 |
1、搜索匹配:re.search(pattern, string)
text = "订单号:ABC123 金额:¥99.8"
if re.search(r'\d+\.\d+', text): # 检查是否有小数print("发现金额")
2、查找所有匹配项:re.findall(pattern, string)
emails = "联系:a@x.com, b@y.cn"
print(re.findall(r'\w+@\w+\.\w+', emails)) # 输出 ['a@x.com', 'b@y.cn']
(1)正则表达式拆解 \w+@\w+\.\w+
-
\w+
:匹配用户名部分-
\w
= 字母/数字/下划线(等价于[a-zA-Z0-9_]
) -
+
= 至少出现1次 -
示例:匹配 "a"、"user123"
-
-
@
:直接匹配邮箱符号 -
\w+
:匹配域名主体-
示例:匹配 "x"、"google"
-
-
\.
:转义匹配真实的点(.
)-
注意:不加反斜杠的
.
会匹配任意字符
-
-
\w+
:匹配顶级域名-
示例:匹配 "com"、"cn"
-
(2)匹配过程演示
以第一个邮箱 "a@x.com" 为例:
原始字符串:联系:a@x.com, b@y.cn↑开始匹配|------------------|匹配流程:\w+ → "a" @ → 匹配@符号 \w+ → "x" \. → 匹配点 \w+ → "com"
3、替换文本:re.sub(pattern, replacement, string)
text = "2023-08-15"
new_text = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', text) # 改为 "08/15/2023"
(1) 正则表达式分解 (\d{4})-(\d{2})-(\d{2})
python
-
(\d{4})
:捕获年(4位数字)-
示例:匹配 "2023"
-
-
-
:匹配日期分隔符(原格式的短横线) -
(\d{2})
:捕获月(2位数字)-
示例:匹配 "08"
-
-
-
:再次匹配分隔符 -
(\d{2})
:捕获日(2位数字)-
示例:匹配 "15"
-
(2)分组编号:
-
第1组:年(
\1
) -
第2组:月(
\2
) -
第3组:日(
\3
)
(3)替换逻辑 r'\2/\3/\1'
替换字符串中的 \数字
对应正则中的分组:
-
\2
→ 第2组(月) -
\3
→ 第3组(日) -
\1
→ 第1组(年)
(4)关键细节
分组顺序:括号从左到右编号,与位置无关
# 错误示范:错误的分组顺序
re.sub(r'(\d{2})-(\d{2})-(\d{4})', r'\3/\1/\2', "15-08-2023") # 正确写法
保留原格式:替换时仅调整分组顺序,不修改内容
# 原始内容中的"08"会被直接引用为\2
分隔符变化:将短横线 -
改为斜杠 /
# 替换字符串中的"/"是普通字符,无需转义
四、核心元字符速查表
符号 | 含义 | 等价写法 | 示例 |
---|---|---|---|
\d | 任意数字 (0-9) | [0-9] | \d+ 匹配 "123" |
\D | 非数字字符 | [^0-9] | \D+ 匹配 "abc" |
\w | 单词字符(字母/数字/下划线) | [a-zA-Z0-9_] | \w+ 匹配 "user123" |
\W | 非单词字符 | [^\w] | \W+ 匹配 "@#$" |
\s | 空白字符(空格、换行、制表符等) | [ \t\n\r\f\v] | \s+ 匹配 " \t" |
\S | 非空白字符 | [^\s] | \S+ 匹配 "Hello" |
. | 任意字符(默认不包含换行) | — | a.c 匹配 "abc" 或 "a c" |
^ | 脱字符 | —— | re.search(r'^Hello', 'Hello World') → 匹配成功 |
$ | 美元符 | —— | re.search(r'World$', 'Hello World') → 匹配成功 |
1、自定义字符集合
用方括号 []
自定义匹配范围:
(1)匹配特定字符
# 匹配元音字母
re.findall(r'[aeiou]', "hello") # ['e', 'o']# 匹配数字或小写字母
re.search(r'[0-9a-z]', "ID: A3") # 匹配 "3"
(2)排除特定字符
在 []
中使用 ^
表示排除:
# 匹配非数字字符
re.findall(r'[^0-9]', "R2D2") # ['R', 'D']
(3) 组合范围
# 匹配十六进制字符(0-9, A-F)
re.findall(r'[0-9A-Fa-f]', "Hex: 1aF") # ['1', 'a', 'F']
2、特殊字符处理
(1)转义符号
匹配正则中的特殊符号(如 .
、*
)时,需用 \
转义:
# 匹配浮点数中的点
re.search(r'\d+\.\d+', "价格 9.99") # 匹配 "9.99"
(2) Unicode 字符(如中文)
Python 的 re
模块默认支持 Unicode:
# 匹配中文字符
re.findall(r'[\u4e00-\u9fa5]+', "Hello 你好!") # ['你好']
五、量词控制重复次数
量词 | 含义 | 示例 | 行为说明 |
---|---|---|---|
* | 0次或多次 | a* 匹配 "", "a", "aaa" | 尽可能多匹配(贪婪模式) |
+ | 1次或多次 | \d+ 匹配 "1", "123" | 至少出现一次 |
? | 0次或1次 | colou?r 匹配 "color"/"colour" | 可选匹配 |
{n} | 精确n次 | \d{4} 匹配4位数字 | 如年份匹配 |
{n,} | 至少n次 | \w{3,} 匹配3个以上字母数字 | 如密码长度验证 |
{n,m} | n到m次 | \d{2,4} 匹配2-4位数字 | 范围控制 |
1、自定义字符集 []
# 匹配元音字母
re.findall(r'[aeiou]', 'hello') # ['e', 'o']# 匹配十六进制字符(0-9, a-f)
re.search(r'[0-9a-fA-F]+', 'Color: #FF00FF') # 匹配 "#FF00FF"
2、排除字符集 [^]
# 匹配非数字字符
re.findall(r'[^0-9]', 'R2-D2') # ['R', '-', 'D']
3、逻辑或 |
# 匹配多种日期格式
pattern = r'\d{4}-\d{2}-\d{2}|\d{2}/\d{2}/\d{4}'
re.findall(pattern, '2023-08-15 或 08/15/2023') # 匹配两者
4、捕获组 ()
# 提取日期各部分
date = '2023-08-15'
match = re.search(r'(\d{4})-(\d{2})-(\d{2})', date)
print(match.groups()) # ('2023', '08', '15')
5、反向引用 \n
# 查找重复单词
re.findall(r'\b(\w+)\b\s+\1\b', 'hello hello world') # ['hello']
6、 非捕获组 (?:)
# 匹配但不捕获组
re.findall(r'(?:Mr|Ms)\. (\w+)', 'Mr. Smith, Ms. Lee') # ['Smith', 'Lee']
六、实战技巧
1、匹配手机号
phone = "138-1234-5678"
match = re.search(r'1[3-9]\d-?\d{4}-?\d{4}', phone)
if match:print(f"找到手机号:{match.group()}")
2、提取网页链接
html = '<a href="https://example.com">点击这里</a>'
links = re.findall(r'href="(https?://[^"]+)"', html) # ['https://example.com']
3、密码强度验证
要求:8-20位,必须包含字母和数字
password = "Passw0rd"
if re.fullmatch(r'(?=.*\d)(?=.*[a-zA-Z]).{8,20}', password):print("密码有效")
七、补充
1、在正则表达式中,使用 ^ 来匹配字符串的开头。
2、在正则表达式中,使用 $ 来匹配字符串结尾。