Python 教程

17.3 分组、贪婪与非贪婪匹配

Python正则表达式教程:分组、贪婪与非贪婪匹配详解

Python 教程

本教程深入浅出地讲解Python中正则表达式的分组、贪婪与非贪婪匹配,包含代码示例和解释,适合编程新手快速入门。

推荐工具
PyCharm专业版开发必备

功能强大的Python IDE,提供智能代码补全、代码分析、调试和测试工具,提高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!

开发工具推荐
Python开发者工具包

包含虚拟环境管理、代码格式化、依赖管理、测试框架等Python开发全流程工具,提高开发效率。特别适合处理复杂数据结构和算法。

获取工具包