python正则分组核心在于是否保存匹配结果:捕获组(()或(?p...))保存内容供group()提取,非捕获组(?:...)仅控制逻辑不保存、不编号。

Python正则中的分组核心在于控制匹配结构和提取内容,关键区别在于“是否保存匹配结果供后续使用”——捕获组会把括号内匹配的内容存进 group(),非捕获组只参与匹配逻辑,不保存。
捕获组:用括号包裹,自动编号,能取值
最基础的分组方式,一对圆括号 () 就是一个捕获组。Python 按左括号出现顺序从 1 开始编号(group(0) 是整个匹配)。
- 例如
r'(\d{4})-(\d{2})-(\d{2})'匹配'2023-12-25',match.group(1)得'2023',group(2)是'12',group(3)是'25' - 支持命名捕获组:
r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'</day></month></year>,之后可用match.group('year')直接取值,更清晰可读 - 重复使用的捕获组(如
(\d+),\s+\1)中\1表示引用第一个捕获组的**实际匹配内容**(不是模式),用于匹配重复字符串
非捕获组:仅分组逻辑,不占编号,不存结果
语法为 (?:...),它让括号内的子表达式具备分组能力(比如配合量词或分支),但不会生成独立 group 编号,也不影响其他捕获组的序号。
- 例如
r'(?:https?|ftp)://\S+'中(?:https?|ftp)表示“匹配 http、https 或 ftp”,但不单独捕获协议名,避免无意义占位 - 搭配量词更实用:
r'(?:ab)+'匹配连续的'ababab',若写成(ab)+虽然也匹配,但group(1)只返回最后一次('ab'),而(?:ab)+不产生干扰,便于专注主匹配 - 在复杂正则里混用时,非捕获组能保持捕获组编号稳定,方便维护和引用
常见误区与注意事项
分组嵌套、编号规则和性能容易踩坑,需特别注意:
立即学习“Python免费学习笔记(深入)”;
- 嵌套捕获组按左括号顺序编号,与层级无关。例如
((a)(b))中,外层是 group(1),内层(a)是 group(2),(b)是 group(3) - 非捕获组
(?:...)内不能再用命名捕获;但命名捕获组本身可以嵌套非捕获组 - 大量使用捕获组会略微增加内存开销和匹配耗时,纯做逻辑分组时优先选
(?:...) -
re.findall()对含捕获组的模式,**默认只返回捕获组内容**(单个组返回字符串列表,多个组返回元组列表);想返回完整匹配,得把整个模式包进一个捕获组,或改用re.finditer()
实战小技巧:快速判断该用哪种分组
问自己两个问题:
- 后续是否需要通过
group()或findall()提取这部分内容?→ 是,用普通捕获组(或命名组) - 只是为了让
|、+、*等作用于多个字符,或提升可读性?→ 否,用(?:...) - 不确定要不要捕获?先写非捕获组,后期需要再改成命名组,避免重构编号










