一、什么是正则表达式?

简单说,正则表达式是一种 “字符串匹配工具”,能按指定规则快速从文本中找符合条件的内容。比如:

  • 从一堆文字里提取所有手机号
  • 验证邮箱格式是否正确
  • 替换文本中的敏感词

它不是 Python 独有的,但 Python 的re模块让使用正则变得特别方便。

二、先记几个最常用的 “匹配符号”

正则表达式的核心是 “规则符号”,先记住这几个最常用的,足够应付 80% 的场景:

符号 含义 例子 匹配结果
. 匹配任意单个字符(除换行) a.b 匹配 “a1b”、“a+b”,不匹配 “ab”(中间少字符)
*星号 前一个字符出现 0 次或多次 ab*c 匹配 “ac”(b 出现 0 次)、“abc”(b1 次)、“abbbc”(b3 次)
前一个字符出现 1 次或多次 ab+c 匹配 “abc”、“abbbc”,不匹配 “ac”(b0 次)
? 前一个字符出现 0 次或 1 次 ab?c 匹配 “ac”(b0 次)、“abc”(b1 次),不匹配 “abbc”(b2 次)
[] 匹配括号内的任意一个字符 a[0-9]b 匹配 “a1b”、“a5b”,不匹配 “aab”(中间是字母)
\d 匹配任意数字(0-9) \d{11} 匹配 11 位数字(如手机号)
\w 匹配字母、数字或下划线 \w+ 匹配 “abc”、“123”、“a_b”
^ 匹配字符串开头 ^abc 只匹配 “abc123”(开头是 abc),不匹配 “xabc”
$ 匹配字符串结尾 abc$ 只匹配 “123abc”(结尾是 abc),不匹配 “abcx”
{m} 匹配前一个字符 m 次
{m, n} 匹配前一个字符 m 到 n 次
*? +? ?? {m,n}? 使 *、+、?、{m,n} 变成非贪婪模式,也就是使这些匹配次数不定的表达式尽可能少的匹配
\ 转义特殊字符
竖杠 匹配 两边任意表达式
(…) 将括起来的表达式分组
\number 匹配数字代表的组合
\A 只匹配字符串开始
\b 匹配空字符串,但只在单词开始或结尾的位置
\B 匹配空字符串,但不能在词的开头或者结尾
\d 主要匹配数字 [0-9]
\D 匹配任何非十进制数字的字符
\s 匹配空白字符,主要包括:空格 \t \n \r \f \v
\S 匹配任何非空白字符
\w 匹配 [a-zA-Z0-9_]
\W 匹配非单词字符
\Z 只匹配字符串尾

三、re 模块常用函数:按需求选着用

re模块提供了一堆工具函数,记住这 5 个最常用的,基本能解决大部分问题。

匹配模式

参数 说明
re.A 让 \w, \W, \b, \B, \d, \D, \s, \S 只匹配 ASCII
re.I 忽略大小写
re.M 多行模式
re.L 由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配
re.S . 匹配包括换行符在内的任意字符
re.U 在 Python3 中是冗余的,因为 Python3 中字符串已经默认为 Unicode
re.X 忽略空格和 # 后面的注释

1. re.search (pattern, string):找第一个匹配的内容

从整个字符串中找第一个符合规则的内容,返回匹配结果(没找到返回 None)。
import re

# 从文本中找第一个手机号(11位数字)
text = "我的电话是13812345678,他的是13987654321"
result = re.search(r'\d{11}', text)  # r表示原生字符串,避免转义问题
print(result.group())  # 输出:13812345678

2. re.match (pattern, string):从开头开始匹配

只检查字符串开头是否符合规则,不符合就返回 None(和 search 的区别!)。

# 检查字符串是否以"hello"开头
text1 = "hello world"
text2 = "hi hello"

print(re.match(r'hello', text1))  # 匹配成功(开头是hello)
print(re.match(r'hello', text2))  # None(开头不是hello)

3. re.findall (pattern, string):找所有匹配的内容

返回所有符合规则的内容,用列表形式保存。

# 提取文本中所有邮箱(简单规则:包含@和.)
text = "邮箱1:a@qq.com,邮箱2:b@gmail.com,邮箱3:c.d@163.com"
emails = re.findall(r'\w+@\w+\.\w+', text)
print(emails)  # 输出:['a@qq.com', 'b@gmail.com', 'c.d@163.com']

4. re.sub (pattern, repl, string):替换匹配的内容

把符合规则的内容替换成指定字符串。

# 把文本中的"敏感词"替换成"***"
text = "这是敏感词,那个也是敏感词,别再说敏感词了"
new_text = re.sub(r'敏感词', '***', text)
print(new_text)  # 输出:这是***,那个也是***,别再说***了

5. re.split (pattern, string):按规则分割字符串

用匹配的内容作为分隔符,把字符串拆成列表。

# 按逗号或分号分割字符串
text = "苹果,香蕉;橘子,西瓜"
result = re.split(r'[,;]', text)  # [,;]表示匹配逗号或分号
print(result)  # 输出:['苹果', '香蕉', '橘子', '西瓜']

四、实战案例:验证手机号格式

手机号规则:11 位数字,以 13/14/15/17/18/19 开头。

import re

def is_phone(phone):
    # 规则:^1[3-9]\d{9}$ 
    # ^1:开头是1;[3-9]:第二位是3-9;\d{9}:后面9位是数字;$:结尾
    return re.match(r'^1[3-9]\d{9}$', phone) is not None

print(is_phone("13812345678"))  # True(符合规则)
print(is_phone("12812345678"))  # False(第二位是2,不符合)
print(is_phone("1381234567"))   # False(只有10位)

五、小技巧:编译正则表达式(提高效率)

如果同一个规则要多次使用,先用re.compile()编译成对象,能加快运行速度:

# 编译正则规则
pattern = re.compile(r'\d{11}')  # 匹配手机号

# 多次使用
text1 = "电话1:13812345678"
text2 = "电话2:13987654321"
print(pattern.search(text1).group())  # 13812345678
print(pattern.search(text2).group())  # 13987654321

总结
正则表达式的核心是 “按规则匹配字符串”,re模块让这个过程变得简单:

记牢常用符号(.、*、+、\d、\w 等)
选对函数:找一个用search,找所有用findall,替换用sub
复杂规则先拆成简单部分,多试多调

刚开始可能觉得符号复杂,多写几个例子(比如验证邮箱、提取身份证号),很快就能上手~

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐