多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Python进阶教程:1_正则表达式 零基础超详细教程

Python进阶教程:1_正则表达式 零基础超详细教程 Python 的所有正则表达式功能都封装在内置re模块中无需额外安装导入即可使用。这些函数覆盖了「格式校验、内容提取、批量替换、文本分割」四大核心场景是处理文本数据的必备工具。本文会逐个讲解每个函数的作用、语法、参数、可运行示例、新手坑点最后附对比总结和易错点零基础也能完全吃透。前置必记导入模块所有操作前先导入reimport re原始字符串r正则规则一律用r规则开头避免反斜杠\和 Python 自身的转义冲突比如\d不用写成\\d。返回值规律匹配类函数match/search匹配成功返回「匹配对象」失败返回None提取类函数findall返回结果列表无匹配返回空列表替换类函数sub返回替换后的新字符串一、核心常用函数按使用频率排序1. re.match ()从字符串开头匹配作用只检查字符串的开头是否符合规则开头不匹配直接返回None匹配成功返回「匹配对象」。语法re.match(pattern, string, flags0)pattern正则规则字符串string待处理的目标字符串flags可选修饰符比如忽略大小写、允许匹配换行等后面统一讲解适用场景格式校验判断字符串是否以指定规则开头配合$可以实现完整的全串格式校验。示例演示import re text1 Python 很好学 text2 学 Python 很有趣 # 1. 开头匹配成功 result1 re.match(rPython, text1) print(result1) # re.Match object; span(0, 6), matchPython print(result1.group()) # 提取匹配到的内容Python # 2. 开头不匹配返回None result2 re.match(rPython, text2) print(result2) # None实战完整校验手机号配合首尾符号如果要校验整个字符串是否是合法手机号必须加^开头和$结尾否则中间符合也会被匹配。def check_phone(phone): # 1开头第二位3-9共11位数字首尾严格匹配 pattern r^1[3-9]\d{9}$ if re.match(pattern, phone): return True return False print(check_phone(13812345678)) # True print(check_phone(a13812345678b)) # False前后有多余字符⚠️ 新手易错re.match只看开头不看结尾。校验完整格式必须加$否则13812345678abc也会被判定为匹配成功。2. re.search ()全文查找第一个匹配项作用在整个字符串中搜索找到第一个符合规则的内容就返回找不到返回None。语法re.search(pattern, string, flags0)和 re.match () 的核心区别表格函数匹配范围适用场景re.match()只匹配字符串开头开头校验、格式校验re.search()全文查找只返回第一个从文本里找第一个符合条件的内容示例演示import re text 我的学号是2024001年龄18岁 # match开头不是数字直接失败 print(re.match(r\d, text)) # None # search全文找第一个数字串成功 result re.search(r\d, text) print(result.group()) # 2024001 总结只想找「有没有、第一个在哪里」用 search只校验开头格式用 match。3. re.findall ()提取所有匹配内容最常用作用找出字符串中所有符合规则的内容返回一个列表没有匹配到就返回空列表。 这是批量提取数据最常用的函数比如提取所有手机号、所有邮箱、所有数字。语法re.findall(pattern, string, flags0)基础示例import re text 语文90分数学95分英语88分物理92分 # 提取所有数字 nums re.findall(r\d, text) print(nums) # [90, 95, 88, 92] # 提取所有科目名称 subjects re.findall(r[\u4e00-\u9fa5](?分), text) print(subjects) # [语文, 数学, 英语, 物理]⚠️ 新手头号大坑带分组时只返回分组内容如果正则里加了括号()分组findall不会返回完整匹配结果只会返回括号里的内容。示例验证import re text 语文90分数学95分 # 不带分组返回完整匹配 res1 re.findall(r语文\d分, text) print(res1) # [语文90分] # 带分组只返回括号里的数字 res2 re.findall(r语文(\d)分, text) print(res2) # [90]这是设计特性不是 bug当你只想提取局部内容时分组可以直接帮你过滤掉多余字符。如果既想要完整匹配又要分组用re.finditer()。4. re.finditer ()查找所有匹配返回迭代器作用和findall功能一样都是找所有匹配项但返回的是迭代器每个元素都是「匹配对象」而不是直接返回字符串。优势节省内存不会一次性把所有结果加载到内存适合处理超大文本信息更全每个结果都是匹配对象可以拿到位置、分组等详细信息语法re.finditer(pattern, string, flags0)示例演示import re text 苹果5元香蕉3元橙子8元 results re.finditer(r([\u4e00-\u9fa5])(\d)元, text) # 遍历迭代器每个item都是匹配对象 for item in results: print(f完整内容{item.group()}) print(f水果名{item.group(1)}价格{item.group(2)}) print(f位置{item.span()}\n)运行结果完整内容苹果5元 水果名苹果价格5 位置(0, 4) 完整内容香蕉3元 水果名香蕉价格3 位置(5, 9) 完整内容橙子8元 水果名橙子价格8 位置(10, 14) 选型建议简单提取用findall方便快捷需要详细信息、处理大文本用finditer。5. re.sub ()替换匹配内容最常用作用把所有匹配到的内容替换成指定内容返回替换后的新字符串。 相当于「高级版替换」可以按规则批量替换比字符串自带的replace()强大得多。语法re.sub(pattern, repl, string, count0, flags0)repl替换成的内容可以是字符串也可以是函数count可选最多替换几次默认0表示全部替换适用场景敏感词替换、格式清洗、统一文本格式、去除多余字符。示例 1基础替换把所有数字替换成***import re text 手机号13812345678身份证110101199001011234 new_text re.sub(r\d, ***, text) print(new_text) # 输出手机号***身份证***示例 2清洗格式把多个连续空格合并成一个空格import re text 我 爱 Python 编程 new_text re.sub(r\s, , text).strip() print(new_text) # 我 爱 Python 编程 示例 3进阶用法 —— repl 是函数repl可以传入一个函数对每个匹配结果做自定义处理后再替换。 比如把所有数字都乘 2import re text 苹果5元香蕉3元橙子8元 def double_num(match_obj): # match_obj 是每个匹配的匹配对象 num int(match_obj.group()) return str(num * 2) new_text re.sub(r\d, double_num, text) print(new_text) # 苹果10元香蕉6元橙子16元6. re.subn ()替换并统计次数作用和re.sub()功能完全一样区别是返回值是一个元组(替换后的新字符串, 替换次数)。示例import re text 语文90数学95英语88 result re.subn(r\d, ***, text) print(result) # (语文***数学***英语***, 3) # 分别取出 new_text, count result print(f替换后{new_text}一共替换了{count}处)适用场景需要知道一共替换了多少处的时候使用。7. re.split ()按正则规则分割字符串作用用匹配到的内容作为分隔符分割字符串返回分割后的子字符串列表。 比字符串自带的split()强大得多支持多种分隔符、复杂规则分割。语法re.split(pattern, string, maxsplit0, flags0)maxsplit可选最大分割次数默认0不限制示例 1按多种标点分割import re text 你好我是小明。很高兴认识你请问你叫什么 # 按中文逗号、句号、感叹号、问号分割 parts re.split(r[。], text) print(parts) # [你好, 我是小明, 很高兴认识你, 请问你叫什么, ]示例 2按任意空白字符分割import re text name:小明 age:18\t score:95\n gender:男 # 按空格、制表符\t、换行符\n 分割 items re.split(r\s, text) print(items) # [name:小明, age:18, score:95, gender:男]8. re.compile ()预编译正则提升效率作用把正则规则提前编译成「正则对象」后续可以直接用这个对象调用 match/search/findall 等方法。优势提升效率同一条正则多次使用时只编译一次不用每次都重新解析规则循环处理大量文本时性能提升明显代码更清晰把规则定义和业务逻辑分开易读易维护语法pattern_obj re.compile(pattern, flags0)编译后的对象自带match()、search()、findall()、sub()等所有方法用法和全局函数完全一致只是不用再传 pattern 参数。示例演示import re # 预编译手机号正则后面反复使用 phone_pattern re.compile(r^1[3-9]\d{9}$) # 直接用编译后的对象调用方法 print(phone_pattern.match(13812345678)) # 匹配成功 print(phone_pattern.match(12345678901)) # None # 也可以用findall等其他方法 text 电话113811112222电话213933334444 print(phone_pattern.findall(text)) # [13811112222, 13933334444] 新手建议同一条规则用 3 次以上就建议用 compile 预编译代码更规范。二、匹配对象Match 对象常用方法re.match()、re.search()、re.finditer()返回的都是「匹配对象」通过它的方法可以提取详细信息这是新手必须掌握的基础。表格方法作用.group()/.group(0)获取完整匹配的内容.group(n)获取第 n 个分组括号里的内容n 从 1 开始.groups()所有分组内容组成的元组.span()返回匹配内容的起止索引(起始, 结束).start()匹配内容的起始索引.end()匹配内容的结束索引完整示例import re text 小明的邮箱是xiaoming163.com result re.search(r([a-zA-Z0-9_])([a-zA-Z0-9.]), text) if result: print(完整邮箱, result.group()) # xiaoming163.com print(用户名, result.group(1)) # xiaoming print(域名, result.group(2)) # 163.com print(所有分组, result.groups()) # (xiaoming, 163.com) print(位置, result.span()) # (6, 22)三、常用修饰符 flagsflags参数用来修改正则的匹配规则多个修饰符用|分隔比如re.I | re.S。新手掌握最常用的 3 个即可修饰符简写作用re.IGNORECASEre.I忽略大小写re.DOTALLre.S让.可以匹配换行符默认.不匹配换行re.MULTILINEre.M多行模式^和$匹配每一行的开头和结尾示例 1忽略大小写import re text Python python PYTHON print(re.findall(rpython, text, re.I)) # [Python, python, PYTHON]示例 2让。匹配换行import re text div你好\n世界/div # 默认.不匹配换行匹配失败 print(re.search(rdiv.*/div, text)) # None # 加re.S.可以匹配换行成功 print(re.search(rdiv.*/div, text, re.S).group()) # div你好 # 世界/div四、函数对比总结表函数核心作用返回值适用场景re.match()开头匹配匹配对象 / None格式校验、开头判断re.search()全文找第一个匹配对象 / None查找是否存在、取第一个结果re.findall()提取所有匹配字符串列表批量提取数据、简单场景首选re.finditer()提取所有匹配匹配对象迭代器大文本、需要详细匹配信息re.sub()替换匹配内容新字符串批量替换、文本清洗re.subn()替换 统计次数(新字符串次数)需要统计替换数量re.split()按规则分割字符串列表多分隔符分割文本re.compile()预编译正则正则对象同规则多次使用提升效率五、新手高频易错点总结match 和 search 搞混match只看字符串开头search才是全文查找。校验格式用 match ^$找内容用 search。findall 带分组只返回分组内容正则里有括号时findall 只返回括号里的内容不是 bug 是特性。需要完整结果用 finditer。忘记加r前缀导致\d、\w等转义符失效正则一律用r包裹。格式校验不加首尾符号校验手机号、邮箱等完整格式必须加^和$否则部分匹配就会通过导致校验失效。.默认不匹配换行跨行匹配内容时记得加re.S修饰符。贪婪模式匹配过多.*默认贪婪匹配会尽可能多吞字符提取标签、括号内容时改成.*?非贪婪模式。
返回列表