首页 / 资讯中心 / 文章详情

Python正则表达式入门:从匹配查找替换到分组与贪婪模式实战

Python正则表达式入门:从匹配查找替换到分组与贪婪模式实战 ★ FEATURED ARTICLE
简介这份PDF资料面向正在学习Python、希望系统掌握正则表达式的开发者与编程初学者聚焦文本匹配、提取与替换等常见场景帮助读者从语法基础过渡到实际应用。资源包内共1个PDF文件压缩包大小约661KB内容以图文讲解为主便于在电脑或移动设备上随时翻阅。目前已有260人学习下载适合作为Python正则入门的轻量级参考材料。资料围绕正则表达式核心知识点展开涵盖元字符、字符集、量词、分组、贪婪与非贪婪匹配、常用函数及典型示例读者可借此理解匹配规则、梳理易错点并逐步建立从模式编写到结果验证的完整思路。对于需要处理日志分析、表单校验、爬虫数据清洗等任务的Python学习者这份文档可作为随查随用的知识手册帮助快速定位语法细节并巩固实践能力。1. 正则表达式到底在干嘛从“在一堆文字里找东西”说起你有没有过这种经历在一份几千行的日志文件里想找出所有包含某个关键词的行或者在一段乱七八糟的文本里只想把手机号、邮箱、日期挑出来。手动翻眼睛会瞎。用普通的查找替换又不够灵活因为你要找的东西“长得不完全一样”——手机号有 11 位数字邮箱有和域名日期可能是2024-01-01也可能是2024/1/1。正则表达式就是干这个的。它是一套用来描述“文字长什么样”的规则你把这套规则写出来程序就能拿着它去文本里自动匹配、查找、替换。打个比方普通查找像是拿一张照片去人群里找一模一样的人正则表达式则是拿一份“特征清单”——身高一米八、戴眼镜、穿红衣服——去找符合条件的人哪怕换件衣服、换个发型只要特征对得上就能认出来。Python 里的正则表达式就是把这套规则用 Python 代码写出来配合re模块使用。搞懂它你处理文本的效率会从“手工挑豆子”变成“机器筛沙子”。这也是为什么它成了 Python 学习路上绕不开的一关。2. 为什么正则表达式值得学文本处理的“万能钥匙”2.1 没有正则的日子字符串方法的天花板Python 自带的字符串方法其实不少find()找位置、replace()换内容、split()切分、startswith()判断开头。处理简单任务够用但一遇到“模糊条件”就露怯。举个例子你要从一段文本里找出所有日期。用find()只能找一个固定字符串比如2024-01-01换一天就找不到。用split()按空格切日期可能和别的词粘在一起。你可能会写一堆if和循环代码又长又容易翻车。正则表达式解决的就是“模式匹配”问题。你描述的不是一个具体字符串而是一类字符串的“形状”。比如\d{4}-\d{2}-\d{2}表示“四个数字一个横杠两个数字一个横杠两个数字”。不管具体是哪一年哪一月只要形状对就能匹配上。提示正则表达式不是 Python 独有的很多语言都支持。但 Python 的re模块语法清晰、文档齐全是入门正则的好选择。2.2 正则的四个核心能力匹配、查找、替换、切分Python 的re模块围绕四个动作展开对应四个常用函数函数作用典型场景re.match()从字符串开头匹配校验输入格式比如手机号re.search()在任意位置找第一个匹配从日志里找第一条错误re.findall()找出所有匹配返回列表提取所有邮箱、链接re.sub()把匹配到的内容替换掉脱敏、清洗数据这四个函数覆盖了文本处理的大部分需求。match和search的区别在于起点match只认开头search全串扫描。很多人第一次用会搞混后面会专门讲。再打个比方match像是检查一篇文章的第一句话是不是标题search像是整篇文章翻一遍找到第一个符合条件的地方就停findall是把所有符合条件的都抄下来sub是拿橡皮擦掉再写上新的。2.3 元字符正则的“字母表”正则表达式由普通字符和元字符组成。普通字符就是abc、123这些匹配自己。元字符则有特殊含义是正则的灵魂。常见的元字符不多但组合起来变化无穷.匹配任意一个字符除了换行\d匹配一个数字等价于[0-9]\w匹配字母、数字、下划线\s匹配空白字符空格、制表符等*前面的内容出现 0 次或多次前面的内容出现 1 次或多次?前面的内容出现 0 次或 1 次{n,m}前面的内容出现 n 到 m 次[]字符集合匹配其中任意一个^匹配开头$匹配结尾这些符号单独看都不难难的是组合起来表达复杂规则。比如^\d{11}$表示“从头到尾正好 11 个数字”可以用来校验手机号格式。\w\w\.\w可以粗略匹配邮箱。注意正则表达式是“区分大小写”的除非你加上re.IGNORECASE标志。写规则时别忘了这一点。3. 正则表达式怎么用从写规则到出结果3.1 编译与匹配re.compile 和 match/search 的配合Python 里用正则有两种方式。一种是直接调用re.match()、re.search()等函数每次传入规则字符串。另一种是先用re.compile()把规则编译成一个正则对象再调用对象的方法。import re # 方式一直接调用 result re.search(r\d, 订单号 12345) print(result.group()) # 输出 12345 # 方式二先编译 pattern re.compile(r\d) result pattern.search(订单号 12345) print(result.group()) # 输出 12345两种方式结果一样。区别在于如果同一个规则要反复用很多次先编译效率更高因为编译过程只做一次。如果只是临时用一下直接调用更省事。match和search返回的是匹配对象不是字符串。要拿到具体内容得用.group()。如果没匹配到返回None。所以实际写代码时通常要先判断import re text 联系邮箱helloexample.com pattern re.compile(r\w\w\.\w) match pattern.search(text) if match: print(找到邮箱, match.group()) else: print(没有找到邮箱)这段代码先编译规则再搜索最后判断结果。\w匹配字母数字下划线是普通字符\.匹配真正的点号因为.在正则里是元字符要加反斜杠转义。3.2 分组与捕获把匹配结果拆开用正则表达式用圆括号()表示分组。分组有两个作用一是把一部分规则当成整体比如(ab)表示ab重复多次二是捕获匹配到的内容方便后续提取。import re text 出生日期1990-05-20 pattern re.compile(r(\d{4})-(\d{2})-(\d{2})) match pattern.search(text) if match: print(完整匹配, match.group(0)) print(年, match.group(1)) print(月, match.group(2)) print(日, match.group(3))group(0)是完整匹配group(1)是第一个括号里的内容以此类推。这样就能把日期拆成年、月、日分别使用。分组是正则表达式从“找到”到“提取”的关键一步。如果括号很多又不想全部捕获可以用(?:...)表示非捕获分组只分组不编号。这在写复杂规则时很有用避免编号混乱。3.3 贪婪与非贪婪为什么匹配结果忽长忽短正则表达式默认是“贪婪”的意思是*、、{n,m}会尽可能多地匹配字符。比如.*去匹配ab结果会匹配整个ab而不是a。因为.*会一直吃到最后一个。要改成“非贪婪”在量词后面加?变成.*?。这样它会尽可能少地匹配遇到第一个就停。import re text ab print(re.search(r.*, text).group()) # 输出 ab print(re.search(r.*?, text).group()) # 输出 a贪婪和非贪婪是初学者最容易翻车的地方之一。写规则时如果发现匹配结果比预期长先检查是不是该加?。提示不是所有场景都要非贪婪。提取 HTML 标签内容时非贪婪通常更符合直觉但处理嵌套结构时正则本身就不擅长该用解析库就用解析库。3.4 替换与切分re.sub 和 re.split 的实用场景re.sub()用来替换匹配到的内容。它的强大之处在于替换内容可以引用分组。import re text 2024-01-01 和 2024-12-31 # 把日期格式从 YYYY-MM-DD 改成 DD/MM/YYYY result re.sub(r(\d{4})-(\d{2})-(\d{2}), r\3/\2/\1, text) print(result) # 输出 01/01/2024 和 31/12/2024这里\1、\2、\3分别代表第一、二、三个分组的内容。替换字符串里用反斜杠加数字引用分组就能实现格式重排。re.split()则按正则规则切分字符串比普通split()更灵活。比如按“逗号、分号、空格”任意一种切分import re text apple, banana; orange grape result re.split(r[,;\s], text) print(result) # 输出 [apple, banana, orange, grape][,;\s]表示“逗号、分号、空白字符中的任意一种出现一次或多次”。这样不管分隔符是哪种、有几个都能正确切分。4. 常见误区与易混概念别在这些地方栽跟头4.1 match 和 search 到底差在哪易混点两个函数名字都像“查找”返回值也类似很多人随手用。为什么混match和search在简单例子里结果一样比如规则是\d、文本是123abc两者都匹配。但一旦文本开头不是数字match就返回Nonesearch还能找到。怎么区分match只从字符串第一个字符开始尝试匹配相当于自带^search会扫描整个字符串找到第一个匹配就返回。校验格式用match提取内容用search。import re text abc123 print(re.match(r\d, text)) # None print(re.search(r\d, text)) # re.Match object; span(3, 6), match1234.2 转义字符什么时候要加反斜杠易混点.、*、、?、(、)、[、]这些符号在正则里有特殊含义但有时候你就是想匹配符号本身。为什么混写规则时脑子里想的是“匹配一个点”但正则把.解释成“任意字符”结果匹配到不该匹配的东西。怎么区分想匹配元字符本身前面加反斜杠。比如\.匹配真正的点号\*匹配星号\(匹配左括号。在 Python 字符串里反斜杠本身也要转义所以通常用原始字符串r...来写正则避免双重转义。import re print(re.search(r\., a.b).group()) # 输出 . print(re.search(r\., axb)) # None因为 axb 里没有真正的点4.3 字符集与分组的区别[] 和 () 不是一回事易混点[abc]和(abc)看起来都是把几个字符放一起但含义完全不同。为什么混两者都用了括号视觉上像同类结构。怎么区分[]是字符集匹配其中任意一个字符。[abc]表示匹配a或b或c中的一个。()是分组把abc当成一个整体匹配的是连续的abc三个字符。[abc]匹配的是a、b、c任意组合的连续串(abc)匹配的是abc、abcabc这样的重复。import re print(re.findall(r[abc], abcabc)) # [abcabc] print(re.findall(r(abc), abcabc)) # [abc]4.4 贪婪匹配的坑为什么结果总比想的长易混点.*看起来是“匹配任意内容”但它的贪婪本性会让结果超出预期。为什么混直觉上觉得.*会匹配到第一个符合条件的就停实际上它会一直吃到最后一个符合条件的字符。怎么区分需要“最短匹配”时在量词后加?。.*?表示非贪婪遇到第一个符合条件的就停。但也要注意非贪婪不是万能的有些场景需要更精确的规则比如用[^]*代替.*?来匹配标签内容。import re text div内容1/divdiv内容2/div print(re.findall(rdiv.*?/div, text)) # 输出 [div内容1/div, div内容2/div]4.5 findall 和 finditer 的选择易混点两者都是找所有匹配但返回形式不同。为什么混名字像功能描述也像。怎么区分findall返回列表元素是字符串或元组有分组时。finditer返回迭代器元素是匹配对象可以拿到位置信息。如果只需要内容用findall如果需要知道匹配在原文中的位置用finditer。import re text a1 b2 c3 print(re.findall(r\d, text)) # [1, 2, 3] for m in re.finditer(r\d, text): print(m.group(), m.start()) # 输出1 12 43 75. 什么时候该用正则什么时候该收手正则表达式很强大但不是所有文本问题都该用它。用对了是利器用错了是给自己挖坑。先看一个具体例子。假设你要从一段文本里提取所有电话号码。电话号码格式可能是138-1234-5678、13812345678、(138) 1234-5678。用正则可以写一个相对宽松的规则import re text 联系方式138-1234-5678 备用13912345678 座机(010) 8888-6666 pattern re.compile(r\(?\d{3,4}\)?[-.\s]?\d{3,4}[-.\s]?\d{4}) results pattern.findall(text) for r in results: print(r)这个规则能匹配多种格式但也不是万能的。如果号码格式再复杂一些规则会变得又长又难维护。这时候就要考虑是不是该用更专业的解析工具或者先做数据清洗再匹配。适合用正则的场景格式相对固定、规则清晰、不需要理解语义。比如校验邮箱格式、提取日期、替换敏感词、按多种分隔符切分。不适合用正则的场景嵌套结构比如 HTML、JSON、需要递归匹配、规则复杂到没人能看懂。HTML 用解析库JSON 用json模块别硬扛。注意正则表达式写出来容易读起来难。如果一条规则超过一行还看不懂加注释或者拆成多步。代码是给人看的顺便给机器执行。从那以后我每次写正则都强制自己先拿几条测试数据跑一遍确认匹配范围符合预期再放进正式代码。尤其是贪婪模式和非贪婪模式不测根本不知道会匹配到哪。希望这些内容能帮你少走一点弯路把正则表达式真正用起来。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站