当前位置:首页>python>零基础学Python第二十六课:文本处理的“核武器”!正则表达式

零基础学Python第二十六课:文本处理的“核武器”!正则表达式

  • 2026-09-02 18:54:10
零基础学Python第二十六课:文本处理的“核武器”!正则表达式

🌟 导读欢迎来到 Python 学习的第二十六站。

想象一个场景:老板甩给你一个几十万字的 Word 文档,里面杂乱无章地夹杂着客户的手机号、邮箱和身份证号。老板要求你:“10分钟内,把所有的手机号都提取出来!” 如果你用传统的 for 循环和 if 去挨个检查字符,不仅代码能写出上百行,而且还会漏掉很多。

这时候,就该请出编程界最著名的文本处理“核武器”——正则表达式(Regular Expression,简称 Regex)。 它虽然看起来像一堆外星乱码,但只要学会了它的规则,提取任何复杂文本都只需一行代码!今天,主编带你零基础、无痛拿下这座大山!🚀

🛡️ 1. 战前准备:引入 re 模块与魔法字母 r

在 Python 中使用正则表达式极其简单,只需要导入内置的 re 模块。

⚠️ 新手必看第一坑:为什么正则前面都要加个 r?在写正则表达式时,你会发现所有大牛的代码,在引号前面都会带一个字母 r(代表 raw,也就是“原汁原味”的意思),比如 r"\d+"。

为什么要这样写呢?因为在 Python 的普通字符串里,反斜杠 \ 具有“魔法(转义)”,比如 \n 代表换行。而正则表达式里也大量使用了 \ 作为符号。为了防止 Python 自作主张把你的正则符号翻译错,加上 r 就等于告诉电脑:“这段文字你不要瞎翻译,它是什么样就是什么样!原封不动地交给正则去处理!”

💡 通俗例子秒懂:

import re# 不加 r 的普通字符串,Python 看到 \n 会自作聪明地换行print("Hello\nWorld") # 输出结果直接断成了两截:# Hello# World# 加上 r 的原生字符串,\n 就被打回原形,只是 \ 和 n 两个普通字符!print(r"Hello\nWorld") # 输出结果:Hello\nWorld

(所以,以后写正则,永远养成加 r 的好习惯,能帮你避开 99% 的灵异报错!)

🧩 2. 拼图游戏:最核心的匹配规则(符号字典)

正则表达式其实就是一个“拼图模板”。它是由不同的符号拼凑起来,去长篇大论里“套”出你需要的内容。我们先来认识最常用的几块核心拼图,并结合具体的例子来理解:

🧑‍🤝‍🧑 第一类:代表“某种字符”的代号(单个字符替换)

  • . (英文句号):万能替身(除了换行符)。 它可以代表任何一个字、字母、符号。

    • 例子: 写正则 r"张.三",它可以匹配到 "张大三"、"张小三"、甚至是 "张@三"。

  • \d (digit):代表 1 个数字(0到9)。

    • 例子: 写正则 r"\d\d\d",它可以匹配任意 3 个连在一起的数字,比如 "123" 或 "952"。

  • \w (word):代表 1 个“字母、数字或下划线”。 (常用来匹配账号名)

    • 例子: 写正则 r"Python\w",它可以匹配 "Python3"、"Python_",但不能匹配 "Python!"(因为感叹号不属于字母/数字/下划线)。

  • \s (space):代表 1 个空白。 (空格、Tab键等)

    • 例子: 写正则 r"Hello\sWorld",完美匹配中间带一个空格的 "Hello World"。

📦 第二类:范围选择 [ ]

方括号的意思是:“一个萝卜一个坑,只能从盒子里挑 1 个”。

  • [abc]:只能是 a、b、c 里的其中一个。

    • 例子:r"[李王张]四",可以匹配 "李四"、"王四"、"张四",但匹配不到 "赵四"。

  • [0-9]:等同于 \d,代表一个数字。

  • [a-zA-Z]:代表任何一个大写或小写英文字母。

🔢 第三类:控制数量的“修饰符” (跟在字符后面)

前面讲的 \d 每次只能匹配一个。如果有一串手机号,难道我们要写 11 次 \d 吗?当然不用,我们有数量修饰符!

  • * (星号):出现 0 次或无数次。 (可有可无,多多益善)

    • 例子:r"啊*",它可以匹配 ""(啥也没有)、"啊"、"啊啊啊啊啊"。

  • + (加号):出现 1 次或无数次。 (至少得有 1 个,多多益善)

    • 例子:r"\d+",这在提取数字时最常用!它代表“连在一起的一长串数字”,可以匹配 "6",也能匹配 "10086"。

  • ? (问号):出现 0 次或 1 次。 (仅仅代表“可选的”)

    • 🌟 极佳实战例子:r"https?"。这里的问号代表前面的 s 可有可无。所以这个正则既能匹配旧网址 "http",也能匹配安全网址 "https"!

  • {n}:精确控制次数。

    • 例子:r"\d{11}",不多不少,完美匹配 11 位连续的手机号!

  • {n,m}:控制次数范围。

    • 例子:r"\w{6,12}",匹配 6 到 12 位的账号名。

⚓ 第四类:定位钉子 ^ 和 $

它们不匹配任何文字,只代表位置边界。

  • ^ (脱字符):代表整个文本的最开头。

  • $ (美元符):代表整个文本的最末尾。

    • 🌟 极佳实战例子: 如果你做网页开发,要求用户输入 6 位数密码。

    • 如果你只写 r"\d{6}",用户输入 "abc123456def" 也能通过(因为它只要包含了连续 6 个数字就行)。

    • 必须写成 r"^\d{6}$"!这相当于加了两颗钉子钉死:从头到尾,必须完完全全只有 6 个数字,哪怕多一个空格也不行!

⚔️ 3. 核心大招:re 模块的 5 大常用方法

规则背熟了,我们该怎么指挥 Python 干活呢?re 模块为你准备了 5 把神兵利器,根据不同的需求来选择:

① findall():全部搜刮(新手最爱!⭐⭐⭐⭐⭐)

作用: 扫描整个长文本,找出所有符合规则的片段,直接打包成一个列表(List)交给你!

import retext = "张三的电话是 13812345678,李四的电话是 13987654321,公司前台:010-12345"# 规则解释:找 11 个连在一起的数字result = re.findall(r"\d{11}", text)print(result) # 极其舒爽的输出:['13812345678', '13987654321']

② search():满世界找,找到第一个就收工

作用: 扫描整个文本,一旦找到第一个匹配的,就立刻停下返回。⚠️ 进阶必坑点: 它返回的不是字符串,而是一个“匹配对象”。你必须调用 .group() 方法,才能把里面的文字抠出来!

import retext = "我的工号是 9527,你的工号是 10086"# 规则解释:找 1个以上的数字match_obj = re.search(r"\d+", text)if match_obj:    # 必须用 .group() 才能看到真面目!它只找了第一个就停了!    print("找到了:", match_obj.group())     # 输出:找到了: 9527

③ match():死心眼的门卫

作用: 极度严格!它只从字符串的最最最开头开始检查。如果开头第一个字不符合规则,直接判定失败(返回 None),后面有再多符合的它也不管!(也需要用 .group() 提取内容)

import retext = "工号 9527"# 试图找数字result1 = re.match(r"\d+", text) print(result1)  # 输出 None!因为开头是中文“工”,不是数字,直接失败!result2 = re.search(r"\d+", text)print(result2.group()) # 换成 search 就能找到 9527 啦!

(💡 总结:search 是全屋搜索,match 是只查门口。日常提取信息用 search,校验开头的格式用 match。)

④ sub():超级无敌替换大法

作用: 类似于 Word 里的“查找并替换”,但它支持复杂的正则规则!语法:re.sub(正则规则, 替换成什么, 原文本)

import retext = "我的手机是13812345678,备用机是13987654321"# 需求:把所有的 11 位手机号,都替换成 "保密"safe_text = re.sub(r"\d{11}", "***保密***", text)print(safe_text)# 输出:我的手机是***保密***,备用机是***保密***

⑤ split():万能切割机

之前我们学过字符串的 .split(" ") 只能按某一个固定的字符切割。如果一句话里既有逗号,又有空格,还有分号,怎么把它完美切开?用正则!

import retext = "苹果,香蕉; 西瓜  草莓"# 规则解释:遇到 逗号、分号、空格(无论几个空格),都给我切开!# [\s,;]+ 意思是:盒子里的空白、逗号、分号,只要连续出现 1 次以上,就作为切割线fruits = re.split(r"[\s,;]+", text)print(fruits)# 完美输出:['苹果', '香蕉', '西瓜', '草莓']

📝 总结时刻:

正则表达式很难背,建议你把这篇文章收藏,用到的时候随时翻看这张总结表:

符号分类

核心符号

含义翻译

代表谁

.

任意字符(非换行)

\d, \w, \s

数字、字母/数字/下划线、空白

[abc]

盒子里挑一个

有多少个

*, +, ?

0或无数个、1或无数个、0或1个

{n}, {n,m}

精确n个、n到m个

三大方法

findall()

找所有,返回列表(最推荐)

search() / match()

找第一个 / 从头找(记得用 .group() 提取文字)

sub() / split()

正则替换 / 正则切割

👇 互动时间

假设你要写一个程序,检查用户输入的是不是一个合法的年份(要求:必须是纯数字,且精确地只有 4 位数字,前后不能有其他乱七八糟的字符)。 你会使用下面哪一个正则表达式配合 re.match() 来进行严谨的校验呢?

A. r"\d" B. r"\d+" C. r"^\d{4}$" D. r"\d{4}"

最新文章

随机文章