re.search()比re.match()更常用,因为其在整串中查找首个匹配,而re.match()仅从开头匹配——如日志"GET /index.html 200 192.168.1.105"中提取IP,match因开头非IP返回None,search则成功匹配"192.168.1.105"。

直接说结论:用 re.findall() 提取多个匹配,re.search() 找第一个,re.match() 只从开头匹配——别一上来就用 re.compile(),除非你要反复用同一模式。
为什么 re.search() 比 re.match() 更常用?
因为 re.match() 要求模式必须从字符串开头匹配,而实际文本里目标内容往往藏在中间。比如提取日志里的 IP 地址:"GET /index.html 200 192.168.1.105",用 re.match(r"\d+\.\d+\.\d+\.\d+", s) 会返回 None,因为开头是 "GET";换成 re.search(r"\d+\.\d+\.\d+\.\d+", s) 就能拿到 "192.168.1.105"。
-
re.match()适合验证格式(如校验邮箱是否“看起来像”以user@开头) -
re.search()是通用提取首选,不挑位置 - 两者都返回
Match对象,要用.group()或.group(1)取值
提取多组内容时,括号分组和 re.findall() 怎么配合?
带括号的正则在 re.findall() 中行为会变:如果正则有且仅有一个捕获组,re.findall() 返回字符串列表;如果有多个捕获组,它返回元组列表;没括号则返回完整匹配字符串列表。
例如从 "price: $19.99, qty: 5" 中同时取价格和数量:
立即学习“Python免费学习笔记(深入)”;
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
import re
s = "price: $19.99, qty: 5"
# 两个括号 → 返回元组列表
re.findall(r"price: \$(\d+\.\d+), qty: (\d+)", s) # [('19.99', '5')]
<h1>只给价格加括号 → 返回字符串列表</h1><p>re.findall(r"price: \$(\d+.\d+), qty: \d+", s) # ['19.99']</p><h1>全不加括号 → 返回完整匹配字符串</h1><p>re.findall(r"price: \$(\d+.\d+), qty: \d+", s) # ['19.99'](注意:这里其实还是按一个组处理)</p><h1>正确写法是去掉括号:</h1><p>re.findall(r"price: \$$\d+.\d+$$, qty: \d+", s) # ['price: $19.99, qty: 5']</p>- 想提多个字段,老实用
re.finditer()配合.groups(),逻辑更可控 - 避免嵌套括号或非捕获组
(?:...)混用导致findall返回结构混乱 - 数字型结果仍是字符串,要转
float()或int()得自己做
中文、换行、空白字符容易出错的点有哪些?
默认情况下 . 不匹配换行符,\s 匹配空格、制表符、换行符,但中文全角空格( )、不间断空格( )不在其中;\w 也不匹配中文字符。
- 跨行匹配加
re.DOTALL标志:re.search(r"a.*b", s, re.DOTALL) - 匹配中文加
re.UNICODE(Python 3 默认开启,但显式写上更稳妥) - 要匹配全角空格,得显式写
[ \u3000\t\n\r]或用[\s\u3000] - 中文标点别硬背 Unicode,用字面量更直观:
r"《([^》]+)》"提取书名号内容
真正麻烦的不是写对正则,而是文本本身不规范:HTML 实体没解码、编码混用(UTF-8 和 GBK 夹杂)、OCR 错字(把 0 识别成 O)。先清洗再匹配,比调正则花的时间多得多。

















