Python学习笔记:正则表达式一文通——从入门到精通

大家好,我是你们的老朋友。今天咱们来聊一聊一个既让人头大、又让人兴奋的东西------正则表达式

如果你刚开始接触它,大概率会觉得:"这玩意儿看着像一串加密过的咒语,鬼才看得懂!" 但等你真的学会之后,你会忍不住感叹:正则表达式就是文本处理的瑞士军刀

想象一下,你需要:

  • 验证手机号是不是 11 位数字?
  • 批量提取日志里的 IP 地址?
  • 清洗掉用户输入中奇怪的符号?

如果没有正则,你可能要写一堆 if-else,还得一个一个循环。 但有了正则,三两行代码就能搞定。

所以今天这一篇,我打算带你从最基础的概念到各种常见用法,把正则的精髓讲透。保证你看完就能上手,工作中直接用。


一、正则到底是个啥?

用一句话概括:正则就是一套专门用于字符串匹配的规则语言

你可以把它理解为"用一套符号写下来的过滤规则",Python 自带的 re 模块就是这把钥匙。

python 复制代码
import re  # Python的正则表达式模块

# 简单示例:检查字符串是否以h开头
result = re.match('h', 'hello')
print(result)  # 匹配成功,返回Match对象

很多人第一次看到正则时,心里的想法是: "这点小事,写个 if 不香吗?"

没错,小场景确实没必要用正则。但当规则一复杂,if else 马上变成灾难,维护起来比天书还难。

而正则写起来可能就一行:又短、又快、又精准


二、五大常用匹配方法

先别急着背各种符号,咱们先搞清楚 re 里最常见的五种操作。

  1. re.match():从头匹配
ini 复制代码
result = re.match('h','hello')  # 成功
print(result.group())           # 输出: h

result = re.match('h','world')  # 失败
print(result)                   # None
  1. re.search():全局找第一个
bash 复制代码
re.search('h','hello world')   # 找到第一个 h
re.search('h','world hello')   # 找到中间的 h
  1. re.findall():找全部
scss 复制代码
results = re.findall('h','hello world hi')
print(results)  # ['h', 'h']
  1. re.finditer():找全部(迭代器版)
python 复制代码
matches = re.finditer(r'\d+','共有3个苹果和5个橙子')
for match in matches:
    print(f"找到数字: {match.group()},位置: {match.span()}")

输出:

makefile 复制代码
找到数字: 3,位置: (2, 3)
找到数字: 5,位置: (8, 9)
  1. re.sub():替换
python 复制代码
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. 单字符匹配

python 复制代码
# . 匹配任意字符(除换行符)
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. 预定义类(速记法)

python 复制代码
# \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. 常见符号

python 复制代码
# * 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. 精确次数

python 复制代码
re.match(r'a{3}','aaa')    # 精确3次
re.match(r'a{2,}','aaa')   # 至少2次
re.match(r'a{2,4}','aaa')  # 2到4次

这几个符号加上前面的字符类,就能拼出大多数日常需求。


五、位置规则:锚点在哪里?

有时候我们不只关心"是什么",还要关心"在哪里"。

python 复制代码
# ^ 匹配开头
re.match('^h','hello')  # 匹配

# $ 匹配结尾
re.search('d$','world') # 匹配

# \b 单词边界
re.search(r'\bword\b','hello word test')  # 匹配

还有分组和或:

python 复制代码
# | 或匹配
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

六、贪婪与非贪婪:能少就少

正则的一个坑就是"贪婪模式"。默认情况下,.* 会吃掉尽可能多的字符。

ini 复制代码
text ='学习python课程,学习Java课程'
result = re.search('学习.*课程', text)
print(result.group())  # 学习python课程,学习Java课程

加个 ? 就变成非贪婪:

ini 复制代码
result = re.search('学习.*?课程', text)
print(result.group())  # 学习python课程

很多新手正则写错,90% 是因为忘记非贪婪。


七、几个超实用案例

1. 提取 URL

python 复制代码
def extract_urls(text):
    pattern = r'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+[/\w.-]*'
    return re.findall(pattern, text)

text = '访问官网 https://www.example.com 或 http://test-site.org/path'
urls = extract_urls(text)
print(urls)
# ['https://www.example.com', 'http://test-site.org/path']

2. 提取中文

python 复制代码
text ='Hello世界!Python编程很有趣。123数字'
chinese_chars = re.findall(r'[\u4e00-\u9fff]+', text)
print(chinese_chars)  # ['世界', '编程很有趣']

3. 数据清洗

python 复制代码
def clean_data(text):
    text = re.sub(r'\s+',' ', text)  # 去掉多余空格
    text = re.sub(r'[^\w\u4e00-\u9fff\s.,!\?]','', text)  # 去掉杂符号
    return text.strip()

dirty_text = '  Hello   世界!@#¥%   Python编程...  '
clean_text = clean_data(dirty_text)
print(clean_text)  # 'Hello 世界! Python编程...'

八、高级技巧

1. 命名分组

python 复制代码
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. 提前编译

python 复制代码
pattern = re.compile(r'\b\w{4,}\b')
text = "正则表达式是一个非常强大的文本处理工具"
long_words = pattern.findall(text)
print(long_words)
# ['正则表达式', '非常', '强大', '文本处理', '工具']

九、写正则要注意啥?

  1. r:用原始字符串避免转义
  2. 多复用 :常用的正则建议 compile 提前编译
  3. 小心 None:匹配不到要判断
  4. 别太复杂:可读性第一,必要时加注释
ini 复制代码
pattern = re.compile(r"""
    ^                   # 开头
    (\w+)               # 用户名
    @                   # @符号
    ([a-zA-Z0-9.-]+)    # 域名
    .                  # 点号
    ([a-zA-Z]{2,4})     # 顶级域名
    $                   # 结束
""", re.VERBOSE)

十、最后的碎碎念

学正则最重要的一点:一定要多写,多试

刚开始你可能觉得像看天书,但等到有一天你能写出一个三行的正则,解决了别人三十行的代码,那种快感简直爆棚。

正则表达式就像是键盘侠的秘密武器,谁掌握了,谁在数据处理的世界里就多了一份底气。

所以,别怕复杂,从最简单的 \d\w 开始,慢慢往上堆。相信我,用不了多久,你就能和正则成为"并肩作战的老伙计"。

相关推荐
Mintopia5 小时前
扩散模型在 Web 图像生成中的技术演进:从“随机噪声”到“浏览器里的画家”
前端·javascript·aigc
召摇5 小时前
简洁语法的逻辑赋值操作符
前端·javascript
Watermelo6175 小时前
复杂计算任务的智能轮询优化实战
大数据·前端·javascript·性能优化·数据分析·云计算·用户体验
龙在天5 小时前
上线还好好的,第二天凌晨白屏,微信全屏艾特我...
前端
hllqkbb5 小时前
从零开始写个deer-flow-mvp-第一天
人工智能·python·rag
芝士加5 小时前
月下载超2亿次的npm包又遭投毒,我学会了搭建私有 npm 仓库!
前端·javascript·开源
前端世界5 小时前
前端必看:为什么同一段 CSS 在不同浏览器显示不一样?附解决方案和实战代码
前端·css
鹏多多6 小时前
Web图像编辑神器tui.image-editor从基础到进阶的实战指南
前端·javascript·vue.js