Python 正则表达式全面教程
2025年10月24日 19:50
一、正则表达式简介
正则表达式(Regular Expression,简称 Regex)是一种用于匹配、查找和替换字符串的模式语言。它能高效处理字符串复杂操作,比如验证邮箱格式、提取手机号、清洗文本数据等,在 Python 数据处理、爬虫开发、自动化测试等场景中广泛应用。
二、Python 正则表达式核心工具:re 模块
Python 内置re模块,提供了所有正则表达式相关的函数。使用前需先导入:
import re |
三、正则表达式基础语法
1. 普通字符
直接匹配自身的字符,如字母、数字、符号(a、5、!等)。
示例:匹配字符串中的 "apple"
pattern = r"apple" # 推荐用原始字符串r"",避免转义字符干扰 text = "I love apple and banana" result = re.search(pattern, text) print(result.group()) # 输出:apple |
2. 元字符(特殊功能字符)
具有特殊含义的字符,需掌握以下常用元字符:
元字符 | 功能说明 | 示例 |
. | 匹配任意单个字符(除换行\n) | r"a.b"匹配 "acb"、"a1b",不匹配 "a\nb" |
^ | 匹配字符串开头 | r"^Hello"匹配 "Hello World",不匹配 "Hi Hello" |
$ | 匹配字符串结尾 | r"World$"匹配 "Hello World",不匹配 "World Hi" |
* | 匹配前面字符 0 次或多次 | r"ab*"匹配 "a"、"ab"、"abb" |
+ | 匹配前面字符 1 次或多次 | r"ab+"匹配 "ab"、"abb",不匹配 "a" |
? | 匹配前面字符 0 次或 1 次(非贪婪匹配基础) | r"ab?"匹配 "a"、"ab" |
[] | 字符类,匹配括号内任意一个字符 | r"[abc]"匹配 "a"、"b"、"c";r"[0-9]"匹配任意数字 |
[^] | 否定字符类,匹配括号外任意一个字符 | r"[^abc]"匹配除 "a/b/c" 外的任意字符 |
| | 逻辑或,匹配左右任意一个表达式 | r"apple|banana"匹配 "apple" 或 "banana" |
() | 分组,将表达式打包为一个整体 | r"(ab)+"匹配 "ab"、"abab" |
3. 预定义字符类(简化写法)
为常用字符集合提供的简写形式:
预定义类 | 等价写法 | 功能说明 |
\d | [0-9] | 匹配任意数字 |
\D | [^0-9] | 匹配非数字 |
\w | [a-zA-Z0-9_] | 匹配字母、数字、下划线 |
\W | [^a-zA-Z0-9_] | 匹配非字母、数字、下划线 |
\s | [ \t\n\r\f] | 匹配空白字符(空格、制表符、换行等) |
\S | [^ \t\n\r\f] | 匹配非空白字符 |
4. 量词(指定匹配次数)
除了*/+/?,还可精确指定匹配次数:
量词 | 功能说明 | 示例 |
{n} | 匹配前面字符恰好 n 次 | r"a{3}"匹配 "aaa" |
{n,} | 匹配前面字符至少 n 次 | r"a{2,}"匹配 "aa"、"aaa" |
{n,m} | 匹配前面字符 n 到 m 次 | r"a{2,3}"匹配 "aa"、"aaa" |
5. 贪婪与非贪婪匹配
• 贪婪匹配(默认):尽可能多匹配字符(如*/+/{n,m})
示例:r"a.*b"匹配 "a1b2b" 时,会匹配整个 "a1b2b"
• 非贪婪匹配:在量词后加?,尽可能少匹配字符
示例:r"a.*?b"匹配 "a1b2b" 时,仅匹配 "a1b"
四、re 模块常用函数
1. re.match(pattern, text)
• 功能:从字符串开头匹配模式,仅返回第一个匹配结果
• 返回值:匹配对象(成功)或 None(失败)
• 示例:
result = re.match(r"^Hello", "Hello Python") print(result.group()) # 输出:Hello(匹配成功) result2 = re.match(r"Hello", "Hi Hello") print(result2) # 输出:None(开头不匹配) |
2. re.search(pattern, text)
• 功能:在整个字符串中查找第一个匹配项(不限制开头)
• 示例:
text = "I love Python, Python is easy" result = re.search(r"Python", text) print(result.group()) # 输出:Python(仅返回第一个匹配) |
3. re.findall(pattern, text)
• 功能:查找字符串中所有匹配项,返回列表(无匹配则返回空列表)
• 示例:提取文本中所有数字
text = "Age: 25, Score: 98, Height: 180" nums = re.findall(r"\d+", text) print(nums) # 输出:['25', '98', '180'] |
4. re.sub(pattern, repl, text, count=0)
• 功能:替换字符串中匹配的内容,count指定替换次数(0 表示全部替换)
• 示例:将文本中的 "Python" 替换为 "Java"
text = "Python is good, Python is fun" new_text = re.sub(r"Python", "Java", text, count=1) print(new_text) # 输出:Java is good, Python is fun |
5. re.split(pattern, text)
• 功能:按匹配的模式分割字符串,返回分割后的列表
• 示例:按逗号或空格分割文本
text = "a,b c;d" parts = re.split(r"[, ;]", text) print(parts) # 输出:['a', 'b', 'c', 'd'] |
五、实际应用案例
1. 验证邮箱格式
规则:包含@和.,@前有字母 / 数字 / 下划线,.后有 2-4 位字母
def is_valid_email(email): pattern = r"^[a-zA-Z0-9_]+@[a-zA-Z0-9]+\.[a-zA-Z]{2,4}$" return bool(re.match(pattern, email)) print(is_valid_email("test@163.com")) # True print(is_valid_email("test@.com")) # False |
2. 提取中国大陆手机号
规则:11 位数字,以 13/14/15/17/18/19 开头
text = "我的手机号是13812345678,朋友的是19987654321,还有个12345678901" phones = re.findall(r"1[3-9]\d{9}", text) print(phones) # 输出:['13812345678', '19987654321'] |
3. 清洗 HTML 标签
去除文本中的 HTML 标签(如<div>、<p>)
html = "<div><h1>标题</h1><p>内容</p></div>" clean_text = re.sub(r"<[^>]+>", "", html) print(clean_text) # 输出:标题内容 |
六、注意事项
1. 原始字符串:始终用r""定义正则模式,避免转义字符(如\d无需写成\\d)。
2. 分组引用:用()分组后,可通过group(1)/group(2)获取分组内容,示例:
result = re.match(r"(\d{3})-(\d{4})", "123-4567") print(result.group(1)) # 123(第一个分组) print(result.group(2)) # 4567(第二个分组) |
1. 性能优化:频繁使用同一模式时,用re.compile()编译模式,提升效率:
pattern = re.compile(r"\d+") # 编译模式 print(pattern.findall("123 abc 456")) # ['123', '456'] print(pattern.findall("789 xyz 012")) # ['789', '012'] |
七、总结与进阶
本教程覆盖了 Python 正则表达式的核心知识点,包括语法、函数和实战案例。若需深入学习,可探索:
• 零宽断言(正向预查、反向预查)
• 正则表达式调试工具(如regex101)
• 复杂场景应用(如 JSON 字符串提取、日志分析)
多练习、多调试是掌握正则表达式的关键,建议结合实际需求编写表达式,逐步提升熟练度。