Python 正则 . * ? .* .*? (.*?) 通俗讲解

导语: 正则表达式是处理字符串、爬虫提取内容的利器,很多新手刚接触正则的时候,会被 .、*、?、.*、.*?、(.*?) 这几个符号绕晕。本文和课堂笔记对齐,用最简单直白的语言 + 可运行代码示例,一次性讲清楚贪婪 / 非贪婪、分组捕获,爬虫提取文本高频使用。

目录

  1. 前置说明
  2. 符号逐个讲解 + 代码示例
  3. 贪婪 .* 和非贪婪 .*? 对比
  4. 分组 (.*?) 爬虫实战
  5. 汇总对比表格
  6. 新手高频踩坑点
  7. 总结

1. 前置说明

正则表达式专门用于字符串处理。 在 Python 中使用正则,需要先导入内置re模块:

复制代码
import re

统一测试字符串(下面示例共用)

复制代码
s = "a123bxxxbyyyb"

2. 符号逐个讲解 + 代码示例

① . 点

含义:匹配除换行符 \n 以外的任意 1 个字符

复制代码
import re
s = "a123bxxxbyyyb"
res = re.findall(r'a.', s)
print(res)  
# 输出:['a1']
# 解释:匹配a后面紧跟任意一个字符

② * 星号

含义:* 前面的字符,出现 0 次或者多次(可以没有,也可以无数个)

复制代码
import re
s = "a123bxxxbyyyb"
res = re.findall(r'x*b', s)
print(res)
# 输出:['xxxb', 'b']
# 解释:匹配x(0个或者多个)后面跟着b

③ ? 问号

含义:? 前面的字符,出现 0 次或者 1 次(最多只能有 1 个)

复制代码
import re
s = "a123bxxxbyyyb"
res = re.findall(r'x?b', s)
print(res)
# 输出:['xb', 'b']
# 解释:x可有可无,最多1个x,后面跟b

④ .* 贪婪模式

含义:贪婪 = 能拿多少拿多少,一直匹配到最后一个结束标记才停下

复制代码
import re
s = "a123bxxxbyyyb"
res = re.findall(r'a.*b', s)
print(res)
# 输出:['a123bxxxbyyyb']
# 解释:从a开始,一直抓到整个字符串最后一个b

⑤ .*? 非贪婪模式

含义:非贪婪 = 能少拿就少拿,碰到第一个结束标记立刻停止

复制代码
import re
s = "a123bxxxbyyyb"
res = re.findall(r'a.*?b', s)
print(res)
# 输出:['a123b']
# 解释:从a开始,遇到第一个b直接结束匹配

⑥ (.*?) 非贪婪 + 分组捕获

含义:() 是分组,括号外面的内容只用来定位,只提取括号内部匹配到的内容

爬虫提取内容最常用!

复制代码
import re
s = "a123bxxxbyyyb"
res = re.findall(r'a(.*?)b', s)
print(res)
# 输出:['123']
# 解释:定位开头a、结尾b,只取出中间部分

3. 贪婪 .* 和非贪婪 .*? 对比(重点)

复制代码
import re
html = "<div>苹果</div><div>香蕉</div>"

# 贪婪 .*
res_greed = re.findall(r"<div>.*</div>", html)
print("贪婪匹配结果:", res_greed)
# 输出:['<div>苹果</div><div>香蕉</div>']
# 坑:直接抓到最后一个</div>,一次性全部吞掉

# 非贪婪 .*?
res_not_greed = re.findall(r"<div>.*?</div>", html)
print("非贪婪匹配结果:", res_not_greed)
# 输出:['<div>苹果</div>', '<div>香蕉</div>']

4. 爬虫实战:只提取标签内文字((.*?) 经典用法)

我们不想要标签本身,只想要标签中间文本,就把.*?放进括号:

复制代码
import re
html = "<div>苹果</div><div>香蕉</div>"
res = re.findall(r"<div>(.*?)</div>", html)
print("提取到内容:", res)
# 输出:['苹果', '香蕉']

5. 汇总对比表

表格

符号 类型 作用说明
. 元字符 匹配任意单个字符(换行\n除外)
* 量词 前面字符:0 次或多次
? 量词 前面字符:0 次或 1 次
.* 贪婪匹配 尽可能多匹配,直到最后一个结束符
.*? 非贪婪匹配 尽可能少匹配,碰到第一个结束符就停
(.*?) 分组 + 非贪婪 只捕获括号里面内容,爬虫提取文本首选

6. 新手高频踩坑点

✅ 坑 1:. 默认不能匹配换行 如果文本有换行,.*? 会匹配失败,需要加上 re.S 参数

复制代码
# 写法示例
re.findall(r'a(.*?)b', text, re.S)

✅ 坑 2:分不清贪婪和非贪婪,爬虫一次性抓超长一大段 只要你需要多次提取,优先用 (.*?),不要直接写 (.*)

✅ 坑 3:? 两个身份

  • 跟在字符后面:量词(0 或 1 次),如 x?
  • 跟在 * / + 后面:开启非贪婪,如 .*?

✅ 坑 4:特殊字符要转义 如果你的分隔符是 . * + ? () 这些正则符号,需要加反斜杠 \


7. 总结

  1. 爬虫提取文本,(.*?) 是最高频写法;
  2. .* 贪婪模式适合一次性抓取从起点到末尾的整段内容;
  3. 记住:问号跟在星号后面 = 关闭贪婪,变成尽可能少拿;
  4. 遇到多行文本,记得带上 re.S。

配套笔记来自日常爬虫学习记录,适合正则入门,后续会更新正则其他元字符、预定义字符集。

相关推荐
Web3&Basketball2 小时前
DeepSeek V4.1 Flash 实测:Token 砍半、Search API 跑通
数据库·人工智能·python·大模型·api调用·deepseek·推理优化
墨子夕2 小时前
设计模式——Java × Python 双语言精讲 · 23 个经典模式 + 现代演进(第一篇)
java·python·设计模式
程序 代码狂人2 小时前
经典 SQL 面试题:连续登录问题的两种经典解法
java·开发语言·算法
Linux实战笔记2 小时前
凌晨 3 点接口超时,排查发现 asyncio 协程里混用了同步 requests 库
python·asyncio·aiohttp·事件循环阻塞·协程调试
weixin_BYSJ19872 小时前
【计算机毕设】房屋租赁系统02647
java·vue.js·spring boot·python·django·课程设计
在世修行2 小时前
智学文枢:数据归谁管、变了怎么通知
python·桌面应用·状态管理·signal·store·pyside
星夜离尘562 小时前
MATLAB 只剩批次摘要怎么合并方差:用 n、mean、M2 保留批间差异
开发语言·matlab
Misnice2 小时前
Python 的数据类型
java·windows·python