17.3 分组、贪婪与非贪婪匹配
Python正则表达式教程:分组、贪婪与非贪婪匹配详解
本教程深入浅出地讲解Python中正则表达式的分组、贪婪与非贪婪匹配,包含代码示例和解释,适合编程新手快速入门。
推荐工具
Python正则表达式教程:分组、贪婪与非贪婪匹配
正则表达式(Regular Expression)是处理文本的强大工具,在Python中通过re模块实现。本教程将重点介绍正则表达式的三个核心概念:分组、贪婪匹配和非贪婪匹配,帮助新人轻松掌握。
1. 正则表达式简介
正则表达式使用模式匹配来搜索或替换字符串。例如,\d匹配数字,\w匹配单词字符。在Python中,首先导入re模块:
import re
2. 分组(Grouping)
分组使用圆括号()将模式的一部分组合起来,以便重用或捕获匹配内容。
2.1 捕获组
捕获组将匹配的子字符串保存起来,可以在后续使用。例如,匹配一个简单的邮箱地址:
pattern = r'(\w+)@(\w+)\.com'
text = 'example@test.com'
match = re.search(pattern, text)
if match:
print('整个匹配:', match.group(0))
print('用户名:', match.group(1))
print('域名:', match.group(2))
# 输出:
# 整个匹配: example@test.com
# 用户名: example
# 域名: test
解释:
(\w+)匹配用户名部分(如example),(\w+)匹配域名部分(如test)。match.group(0)返回整个匹配字符串,match.group(1)和match.group(2)分别返回第一个和第二个捕获组的内容。
2.2 非捕获组
使用?:前缀创建非捕获组,它匹配但不保存匹配内容,提高效率。例如:
pattern = r'(?:\w+)@(\w+)\.com'
text = 'example@test.com'
match = re.search(pattern, text)
if match:
print('捕获组数量:', match.groups())
# 输出: ('test',) 只捕获域名,用户名不捕获
3. 贪婪匹配(Greedy Matching)
默认情况下,量词(如*, +, ?, {n,m})会尽可能多地匹配字符,这就是贪婪匹配。
示例:使用.*匹配任意字符(贪婪)。
pattern = r'<.*>'
text = '<p>Hello</p> <div>World</div>'
match = re.search(pattern, text)
if match:
print('贪婪匹配:', match.group())
# 输出: <p>Hello</p> <div>World</div>
解释:.*匹配从第一个<到最后一个>之间的所有字符,包括中间的内容。
常用贪婪量词:
*:匹配0次或多次,尽可能多。+:匹配1次或多次,尽可能多。?:匹配0次或1次,尽可能多。{n,m}:匹配n到m次,尽可能多。
4. 非贪婪匹配(Non-greedy Matching)
非贪婪匹配使用量词后加?,如*?、+?、??,尽可能少地匹配字符。
示例:使用.*?匹配任意字符(非贪婪)。
pattern = r'<.*?>'
text = '<p>Hello</p> <div>World</div>'
match = re.search(pattern, text)
if match:
print('非贪婪匹配:', match.group())
# 输出: <p>
解释:.*?匹配从第一个<到下一个>之间的字符,找到最短匹配,即<p>。
要匹配所有标签,可以使用re.findall:
matches = re.findall(r'<.*?>', text)
print('所有匹配:', matches)
# 输出: ['<p>', '</p>', '<div>', '</div>']
5. 贪婪与非贪婪比较
通过示例对比:
text = 'abc123def'
pattern_greedy = r'\w+'
pattern_non_greedy = r'\w+?'
match_greedy = re.search(pattern_greedy, text)
match_non_greedy = re.search(pattern_non_greedy, text)
print('贪婪匹配:', match_greedy.group()) # 输出: abc123def
print('非贪婪匹配:', match_non_greedy.group()) # 输出: a
解释:贪婪量词\w+匹配整个单词,而非贪婪\w+?只匹配第一个字符。
6. 实践练习
自己尝试修改代码,理解分组、贪婪和非贪婪:
- 分组:捕获电话号码的区号和号码。
- 贪婪与非贪婪:从HTML标签中提取内容。
7. 总结
- 分组:使用
()组织模式,捕获或非捕获匹配部分。 - 贪婪匹配:量词默认行为,尽可能多地匹配。
- 非贪婪匹配:量词后加
?,尽可能少地匹配。
学习正则表达式需要多练习,建议结合Python官方文档或在线工具如regex101.com进行实验。Happy coding!
开发工具推荐