专业的JAVA编程教程与资源

网站首页 > java教程 正文

Python 正则表达式教程 第 4 章:贪婪与非贪婪匹配

temp10 2025-09-24 03:46:24 java教程 2 ℃ 0 评论


点击头像,进入个人中心,查看文章合集,还有更多Python相关的精彩教程等着你!

Python 正则表达式教程 第 4 章:贪婪与非贪婪匹配

在前几章中,我们学习了正则的 基础语法、分组、Flags
本章我们要解决一个常见问题:
为什么正则有时候会“匹配太多”?


4.1 什么是贪婪匹配?

正则默认是 贪婪(Greedy)模式

  • 在满足条件的情况下,会尽可能多地匹配内容。

示例:

import re

text = "<div>hello</div><div>world</div>"

pattern = r"<div>.*</div>"
match = re.search(pattern, text)
print(match.group())

输出:

<div>hello</div><div>world</div>

问题:它把两个 <div> 一起吞掉了。


4.2 什么是非贪婪匹配?

非贪婪(Lazy/Non-Greedy)模式:

  • 在满足条件的情况下,尽可能少地匹配。
  • 通过在量词后加 ? 实现。

示例:

import re

text = "<div>hello</div><div>world</div>"

pattern = r"<div>.*?</div>"  # 加了 ?
matches = re.findall(pattern, text)
print(matches)

输出:

['<div>hello</div>', '<div>world</div>']

4.3 常见量词的贪婪 vs 非贪婪

贪婪(默认)

非贪婪

* —— 尽可能多

*? —— 尽可能少

+ —— 尽可能多

+? —— 尽可能少

? —— 0 或 1(贪婪时尽量匹配 1)

?? —— 0 或 1(非贪婪时尽量匹配 0)

{m,n} —— 匹配 m 到 n 次,尽量多

{m,n}? —— 匹配 m 到 n 次,尽量少


4.4 示例:提取引号中的内容

import re

text = 'He said "hello" and "world".'

# 贪婪
print(re.findall(r'"(.*)"', text))
# ['hello" and "world']

# 非贪婪
print(re.findall(r'"(.*?)"', text))
# ['hello', 'world']

4.5 示例:解析 HTML 标签

import re

html = "<p>first</p><p>second</p>"

# 贪婪
print(re.findall(r"<p>.*</p>", html))
# ['<p>first</p><p>second</p>']

# 非贪婪
print(re.findall(r"<p>.*?</p>", html))
# ['<p>first</p>', '<p>second</p>']

4.6 图示对比

字符串:

<p>abc</p><p>def</p>
  • 贪婪匹配 <p>.*</p>
<p>abc</p><p>def</p>
^^^^^^^^^^^^^^^^^^^
一次性吞掉所有
  • 非贪婪匹配 <p>.*?</p>
<p>abc</p><p>def</p>
^^^^^^^^^
          ^^^^^^^^^
逐个匹配

4.7 小练习

请尝试写出正则,完成以下任务:

  1. 从字符串 "The prices are $5, $10, and $100" 中提取所有美元金额(数字部分即可)。
  2. 从文本 "<title>My Page</title><title>Your Page</title>" 中提取所有 <title> 标签的内容。
  3. 用一个正则,提取 "aaabbbccc" 中 连续的相同字母分组,结果应为 ['aaa','bbb','ccc']。

本章你学到了:

  • 默认正则是 贪婪模式
  • ? 可以把量词变为 非贪婪模式
  • 贪婪 vs 非贪婪在实际解析 HTML/XML、引号内容时非常重要

下一章(第 5 章),我们会学习 正则表达式中的零宽断言(前后查找),掌握更强大的匹配控制力。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表