大家好,我是你们的老朋友。今天咱们来聊一聊一个既让人头大、又让人兴奋的东西——正则表达式。
如果你刚开始接触它,大概率会觉得:“这玩意儿看着像一串加密过的咒语,鬼才看得懂!” 但等你真的学会之后,你会忍不住感叹:正则表达式就是文本处理的瑞士军刀。
想象一下,你需要:
- 验证手机号是不是 11 位数字?
- 批量提取日志里的 IP 地址?
- 清洗掉用户输入中奇怪的符号?
如果没有正则,你可能要写一堆 if-else,还得一个一个循环。 但有了正则,三两行代码就能搞定。
所以今天这一篇,我打算带你从最基础的概念到各种常见用法,把正则的精髓讲透。保证你看完就能上手,工作中直接用。
一、正则到底是个啥?
用一句话概括:正则就是一套专门用于字符串匹配的规则语言。
你可以把它理解为“用一套符号写下来的过滤规则”,Python 自带的 re
模块就是这把钥匙。
import re # Python的正则表达式模块
# 简单示例:检查字符串是否以h开头
result = re.match('h', 'hello')
print(result) # 匹配成功,返回Match对象
很多人第一次看到正则时,心里的想法是: “这点小事,写个 if 不香吗?”
没错,小场景确实没必要用正则。但当规则一复杂,if else 马上变成灾难,维护起来比天书还难。
而正则写起来可能就一行:又短、又快、又精准。
二、五大常用匹配方法
先别急着背各种符号,咱们先搞清楚 re
里最常见的五种操作。
re.match()
:从头匹配
result = re.match('h','hello') # 成功
print(result.group()) # 输出: h
result = re.match('h','world') # 失败
print(result) # None
2. re.search()
:全局找第一个
re.search('h','hello world') # 找到第一个 h
re.search('h','world hello') # 找到中间的 h
3. re.findall()
:找全部
results = re.findall('h','hello world hi')
print(results) # ['h', 'h']
4. re.finditer()
:找全部(迭代器版)
matches = re.finditer(r'd+','共有3个苹果和5个橙子')
for match in matches:
print(f"找到数字: {match.group()},位置: {match.span()}")
输出:
找到数字: 3,位置: (2, 3)
找到数字: 5,位置: (8, 9)
5. re.sub()
:替换
text = "今天是2023-12-15,明天是2023-12-16"
new_text = re.sub(r'd{4}-d{2}-d{2}','XXXX-XX-XX', text)
print(new_text)
# 输出: 今天是XXXX-XX-XX,明天是XXXX-XX-XX
这五个函数,基本覆盖了 80% 的正则应用场景。
三、字符匹配规则(别硬背,用场景记)
正则里最让人头疼的就是各种符号。我的建议是——别死记硬背,最好和实际场景绑定着记。
1. 单字符匹配
# . 匹配任意字符(除换行符)
re.match('.','a') # 匹配
re.match('.','1') # 匹配
re.match('.','n') # 不匹配
# [] 匹配集合
re.match('[abc]','a') # 匹配 a/b/c
re.match('[a-z]','m') # 匹配任意小写字母
re.match('[0-9]','5') # 匹配数字
2. 预定义类(速记法)
# d 匹配数字
re.match(r'd','123') # 匹配1
# D 非数字
re.match(r'D','abc') # 匹配a
# s 空格、制表符等
re.match(r's',' hello') # 匹配空格
# w 字母数字下划线
re.match(r'w','hello') # 匹配h
这些符号一旦熟练,写正则就像写公式一样顺手。
四、数量规则:出现几次?
1. 常见符号
# * 0次或多次
re.match(r'a*','aaa') # 匹配aaa
re.match(r'a*','') # 匹配空
# + 1次或多次
re.match(r'a+','aaa') # 匹配aaa
re.match(r'a+','') # 不匹配
# ? 0次或1次
re.match(r'a?','a') # 匹配a
re.match(r'a?','') # 匹配空
2. 精确次数
re.match(r'a{3}','aaa') # 精确3次
re.match(r'a{2,}','aaa') # 至少2次
re.match(r'a{2,4}','aaa') # 2到4次
这几个符号加上前面的字符类,就能拼出大多数日常需求。
五、位置规则:锚点在哪里?
有时候我们不只关心“是什么”,还要关心“在哪里”。
# ^ 匹配开头
re.match('^h','hello') # 匹配
# $ 匹配结尾
re.search('d$','world') # 匹配
# b 单词边界
re.search(r'bwordb','hello word test') # 匹配
还有分组和或:
# | 或匹配
re.match('a|b','a') # 匹配a
re.match('a|b','b') # 匹配b
# () 分组捕获
result = re.match(r'(w+)-(d+)','order-12345')
print(result.group(1)) # order
print(result.group(2)) # 12345
六、贪婪与非贪婪:能少就少
正则的一个坑就是“贪婪模式”。默认情况下,.*
会吃掉尽可能多的字符。
text ='学习python课程,学习Java课程'
result = re.search('学习.*课程', text)
print(result.group()) # 学习python课程,学习Java课程
加个 ?
就变成非贪婪:
result = re.search('学习.*?课程', text)
print(result.group()) # 学习python课程
很多新手正则写错,90% 是因为忘记非贪婪。
七、几个超实用案例
1. 提取 URL
def extract_urls(text):
pattern = r'https?://(?:[-w.]|(?:%[da-fA-F]{2}))+[/w.-]*'
return re.findall(pattern, text)
text = '访问官网 https://www.exa**mp*le.com 或 http://test-site.org/path'
urls = extract_urls(text)
print(urls)
# ['https://www.e*xa*mpl*e.com', 'http://test-site.org/path']
2. 提取中文
text ='Hello世界!Python编程很有趣。123数字'
chinese_chars = re.findall(r'[u4e00-u9fff]+', text)
print(chinese_chars) # ['世界', '编程很有趣']
3. 数据清洗
def clean_data(text):
text = re.sub(r's+',' ', text) # 去掉多余空格
text = re.sub(r'[^wu4e00-u9fffs.,!?]','', text) # 去掉杂符号
return text.strip()
dirty_text = ' Hello 世界!@#¥% Python编程... '
clean_text = clean_data(dirty_text)
print(clean_text) # 'Hello 世界! Python编程...'
八、高级技巧
1. 命名分组
text ="姓名: 张三, 年龄: 25, 城市: 北京"
pattern = r"姓名: (?P<name>w+), 年龄: (?P<age>d+), 城市: (?P<city>w+)"
match= re.search(pattern, text)
if match:
print(f"姓名: {match.group('name')}")
print(f"年龄: {match.group('age')}")
print(f"城市: {match.group('city')}")
2. 提前编译
pattern = re.compile(r'bw{4,}b')
text = "正则表达式是一个非常强大的文本处理工具"
long_words = pattern.findall(text)
print(long_words)
# ['正则表达式', '非常', '强大', '文本处理', '工具']
九、写正则要注意啥?
-
加
r
:用原始字符串避免转义 -
多复用:常用的正则建议
compile
提前编译 - 小心 None:匹配不到要判断
- 别太复杂:可读性第一,必要时加注释
pattern = re.compile(r"""
^ # 开头
(w+) # 用户名
@ # @符号
([a-zA-Z0-9.-]+) # 域名
. # 点号
([a-zA-Z]{2,4}) # 顶级域名
$ # 结束
""", re.VERBOSE)
十、最后的碎碎念
学正则最重要的一点:一定要多写,多试。
刚开始你可能觉得像看天书,但等到有一天你能写出一个三行的正则,解决了别人三十行的代码,那种快感简直爆棚。
正则表达式就像是键盘侠的秘密武器,谁掌握了,谁在数据处理的世界里就多了一份底气。
所以,别怕复杂,从最简单的 d
和 w
开始,慢慢往上堆。相信我,用不了多久,你就能和正则成为“并肩作战的老伙计”。