Python 正则表达式入门:从匹配手机号到提取文本内容
在日常开发中,我们经常会遇到这类需求:
- 从一段文字里找出手机号;
- 从用户输入中提取邮箱;
- 把字符串里的数字统一替换掉;
- 按多种分隔符拆分文本;
- 从简单 HTML 片段中提取标签内容。
这些场景都非常适合使用正则表达式。
Python 内置的 re 模块提供了一套完整的正则工具。本文会从几个最常见的方法开始,结合示例代码,带你快速理解 Python 正则表达式的基本用法。
1. 引入 re 模块
使用正则表达式之前,需要先导入 Python 的内置模块 re:
python
import re
re 是 regular expression 的缩写,也就是正则表达式。
它可以帮助我们按照某种规则去匹配、查找、替换或分割字符串。
2. 使用 re.search 查找第一个匹配项
假设现在有一段文本:
python
text = "我的手机号是 13812345678,邮箱是 test@example.com"
我们想从里面找出手机号,可以使用 re.search():
python
phone = re.search(r"1[3-9]\d{9}", text)
if phone:
print(f"找到手机号:{phone.group()}")
输出结果:
text
找到手机号:13812345678
这里的正则表达式是:
python
r"1[3-9]\d{9}"
它的含义是:
1:手机号以数字1开头;[3-9]:第二位是3到9之间的数字;\d{9}:后面再跟 9 个数字。
所以它可以匹配类似 13812345678 这样的手机号。
需要注意的是,re.search() 只会返回第一个匹配结果。如果找到了,返回一个匹配对象;如果没找到,返回 None。
因此实际使用时,通常要先判断:
python
if phone:
print(phone.group())
其中 group() 用来取出真正匹配到的字符串。
3. 使用 re.search 查找邮箱
我们还可以继续从同一段文本中查找邮箱:
python
email = re.search(r"\w+@\w+\.\w+", text)
if email:
print(f"找到邮箱:{email.group()}")
输出结果:
text
找到邮箱:test@example.com
这个正则表达式:
python
r"\w+@\w+\.\w+"
可以拆成几部分理解:
\w+:匹配一个或多个字母、数字或下划线;@:匹配邮箱中的@符号;\w+:匹配域名主体;\.:匹配真正的点号;\w+:匹配后缀。
为什么点号要写成 \.?
因为在正则表达式里,. 有特殊含义,表示"任意字符"。如果我们想匹配普通的点号,就需要用反斜杠进行转义。
4. 使用 re.findall 查找所有匹配项
re.search() 只会找第一个结果。
如果我们想找出所有匹配内容,可以使用 re.findall()。
比如下面这段文本中有多个价格:
python
text = "价格:100元、200元、350元"
prices = re.findall(r"\d+", text)
print(prices)
输出结果:
text
['100', '200', '350']
这里的正则表达式是:
python
r"\d+"
它表示匹配一个或多个数字。
findall() 会把所有匹配到的结果放进一个列表中返回。
所以当你需要"批量提取"内容时,findall() 非常常用。
5. 使用 re.sub 替换字符串
正则不仅能查找,还能替换。
比如我们想把日期中的数字全部替换成 X:
python
text = "今天是2026年02月19日"
result = re.sub(r"\d+", "X", text)
print(result)
输出结果:
text
今天是X年X月X日
re.sub() 的基本格式是:
python
re.sub(pattern, replacement, string)
也就是:
pattern:要匹配的正则规则;replacement:替换成什么;string:在哪个字符串里替换。
在这个例子中,\d+ 会匹配连续数字,所以 2026、02、19 都会被替换成 X。
6. 使用 re.split 按多个分隔符拆分字符串
普通字符串的 split() 一次通常只能按一种分隔符拆分。
但实际数据经常不那么规整,比如:
python
text = "张三;李四,王五 赵六"
这里的名字之间有分号、逗号和空格。
这时可以使用 re.split():
python
names = re.split(r"[;,\s]+", text)
print(names)
输出结果:
text
['张三', '李四', '王五', '赵六']
这个正则表达式:
python
r"[;,\s]+"
含义是:
[]:字符集合;;:匹配分号;,:匹配逗号;\s:匹配空白字符;+:匹配一次或多次。
也就是说,只要遇到分号、逗号或空白字符,就可以作为分隔符。
7. 常用正则符号速查
下面这些符号是写正则表达式时最常见的基础语法。
| 符号 | 含义 |
|---|---|
. |
匹配任意字符,换行符除外 |
\d |
匹配数字,相当于 [0-9] |
\D |
匹配非数字 |
\w |
匹配字母、数字、下划线 |
\W |
匹配非字母、数字、下划线 |
\s |
匹配空白字符 |
\S |
匹配非空白字符 |
^ |
匹配字符串开头 |
$ |
匹配字符串结尾 |
* |
匹配 0 次或多次 |
+ |
匹配 1 次或多次 |
? |
匹配 0 次或 1 次 |
{n} |
匹配恰好 n 次 |
{n,m} |
匹配 n 到 m 次 |
[] |
字符集合 |
| ` | ` |
() |
分组 |
刚开始学习正则时,不需要一次性记住所有复杂语法。
先掌握 \d、\w、\s、+、*、[]、^、$ 这些基础符号,就已经可以解决很多实际问题。
8. 实战一:验证手机号
前面我们用 search() 从文本中找手机号。
如果现在要判断一个字符串是不是完整的手机号,可以使用 re.match():
python
phone_pattern = r"^1[3-9]\d{9}$"
print(re.match(phone_pattern, "13812345678"))
这里的规则比前面更严格:
python
r"^1[3-9]\d{9}$"
其中:
^表示字符串开头;$表示字符串结尾;1[3-9]\d{9}表示手机号规则。
加上 ^ 和 $ 之后,意味着整个字符串必须完整符合手机号格式。
如果不加它们,只要字符串中包含一段符合规则的内容,也可能被匹配到。
9. 实战二:验证邮箱
邮箱验证可以写成这样:
python
email_pattern = r"^[\w.+-]+@[\w-]+\.[\w.]+$"
print(re.match(email_pattern, "test@example.com"))
这个表达式支持更常见的邮箱格式:
- 用户名部分允许字母、数字、下划线、点号、加号和短横线;
- 中间必须有
@; - 域名部分允许字母、数字、下划线和短横线;
- 后缀部分允许字母、数字、下划线和点号。
不过要注意,真实世界中的邮箱规则非常复杂。
在业务系统中,如果只是做基础格式校验,这样的正则通常够用;如果是严肃的注册、登录或邮件投递场景,还需要结合邮件发送验证。
10. 实战三:提取 HTML 标签内容
代码中还有一个提取 HTML 标签内容的例子:
python
html = "<h1>标题</h1><p>段落</p>"
contents = re.findall(r"<\w+>(.*?)</\w+>", html)
print(contents)
输出结果:
text
['标题', '段落']
这个正则表达式是:
python
r"<\w+>(.*?)</\w+>"
可以这样理解:
<\w+>:匹配开始标签,比如<h1>、<p>;(.*?):提取标签中间的内容;</\w+>:匹配结束标签,比如</h1>、</p>。
这里的 (.*?) 很关键。
其中:
()表示分组,findall()会优先返回分组内容;.表示任意字符;*表示 0 次或多次;?表示非贪婪匹配。
如果没有 ?,正则可能会尽可能多地匹配内容,导致结果不符合预期。
需要提醒的是,正则可以处理简单 HTML 片段,但不适合解析复杂 HTML 文档。
如果是正式爬虫或网页解析任务,更推荐使用 BeautifulSoup、lxml 这类专门的 HTML 解析库。
11. search、match、findall、sub、split 怎么选
可以用下面这张表快速判断:
| 方法 | 用途 |
|---|---|
re.search() |
查找第一个匹配项 |
re.match() |
从字符串开头开始匹配 |
re.findall() |
找出所有匹配内容 |
re.sub() |
替换匹配内容 |
re.split() |
按正则规则分割字符串 |
简单来说:
- 想找一个,用
search(); - 想从开头验证,用
match(); - 想提取全部,用
findall(); - 想替换文本,用
sub(); - 想按复杂分隔符切分,用
split()。
12. 为什么正则字符串前面常加 r
你会发现示例中的正则表达式大多写成这样:
python
r"\d+"
前面的 r 表示原始字符串。
它可以减少反斜杠转义带来的困扰。
比如正则中的 \d 表示数字,如果不用原始字符串,在更复杂的表达式中就很容易遇到双重转义问题。
所以写 Python 正则时,一个好习惯是:
正则表达式尽量使用
r"..."这种原始字符串形式。
小结
本文从几个常见例子出发,介绍了 Python re 模块的基础用法。
核心内容包括:
- 用
re.search()查找手机号和邮箱; - 用
re.findall()提取所有数字; - 用
re.sub()替换匹配内容; - 用
re.split()按多个分隔符拆分文本; - 理解常见正则符号;
- 使用
re.match()验证手机号和邮箱格式; - 用分组和非贪婪匹配提取简单标签内容。
正则表达式刚开始看起来有点像"符号密码",但它的核心思想其实很简单:
用一套规则去描述你想匹配的字符串。
当你掌握了常用符号和几个基础方法之后,就可以用正则快速完成很多文本处理任务。