导语: 正则表达式是处理字符串、爬虫提取内容的利器,很多新手刚接触正则的时候,会被
.、*、?、.*、.*?、(.*?)这几个符号绕晕。本文和课堂笔记对齐,用最简单直白的语言 + 可运行代码示例,一次性讲清楚贪婪 / 非贪婪、分组捕获,爬虫提取文本高频使用。
目录
- 前置说明
- 符号逐个讲解 + 代码示例
- 贪婪
.*和非贪婪.*?对比 - 分组
(.*?)爬虫实战 - 汇总对比表格
- 新手高频踩坑点
- 总结
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. 总结
- 爬虫提取文本,
(.*?)是最高频写法; .*贪婪模式适合一次性抓取从起点到末尾的整段内容;- 记住:问号跟在星号后面 = 关闭贪婪,变成尽可能少拿;
- 遇到多行文本,记得带上
re.S。
配套笔记来自日常爬虫学习记录,适合正则入门,后续会更新正则其他元字符、预定义字符集。