别死记硬背了!用这7个真实数据清洗场景,彻底搞懂Python正则表达式

正则表达式就像程序员手中的瑞士军刀,面对杂乱无章的文本数据时,它能帮你精准地切割、提取和重组。但很多教程把它教成了数学公式,让人背得头疼却不知如何实战。今天我们就用7个真实的数据清洗场景,带你重新认识这个文本处理利器。

1. 从混杂文本中提取手机号

假设你手头有一堆用户留言,需要提取所有手机号。传统字符串操作需要写11层循环判断,而正则表达式只需一行:

import re
text = "联系我:13800138000,备用号13512345678,微信同号"
phones = re.findall(r'\d{11}', text)
print(phones)  # 输出:['13800138000', '13512345678']

这里的关键是\d{11}:

  • \d匹配任意数字
  • {11}表示精确匹配11次

常见坑点:

  • 有些号码带国际区号(如+86)
  • 存在空格或连接符(138-0013-8000)
  • 需要验证号码有效性(如不以0开头)

改进版正则:

r'(?<!\d)(1[3-9]\d{9})(?!\d)'

2. 验证邮箱格式合法性

用户注册时,邮箱验证是基本操作。一个健壮的邮箱正则应该考虑:

email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'

这个正则分解来看:

  • ^和$确保整串是邮箱
  • [a-zA-Z0-9._%+-]+匹配用户名部分
  • @后接域名
  • \.[a-zA-Z]{2,}确保顶级域名至少2位

测试案例:

emails = ["user@example.com", "invalid.email", "name@sub.domain.co"]
for email in emails:
    print(f"{email}: {bool(re.match(email_pattern, email))}")

3. 清洗HTML标签内容

爬虫抓取的网页常带HTML标签,用正则可以快速净化:

dirty_html = "<div>正文<p>段落</p></div>"
clean_text = re.sub(r'<[^>]+>', '', dirty_html)
print(clean_text)  # 输出:正文段落

技巧点:

  • <[^>]+>匹配所有尖括号内容
  • re.sub实现替换
  • 更复杂的HTML建议用BeautifulSoup

4. 拆分含中英文的字符串

处理混合字符串时,常规的split()会失效:

mixed_str = "Python3.9发布,新增了Pattern匹配语法"
parts = re.split(r'(\W+)', mixed_str)
print(parts)  # ['Python3', '.', '9', '发布,新增了', 'Pattern', '匹配语法']

关键点:

  • \W匹配非单词字符
  • 括号()保留分隔符
  • 适用于中英文分词场景

5. 提取日志中的关键信息

分析Nginx日志时,需要提取特定字段:

127.0.0.1 - - [10/Oct/2023:13:55:36 +0800] "GET /api/user HTTP/1.1" 200 432

提取正则:

log_pattern = r'(\d+\.\d+\.\d+\.\d+).*?\[(.*?)\].*?"(\w+) (.*?) .*?" (\d+) (\d+)'
match = re.search(log_pattern, log_line)
print(match.groups())  # ('127.0.0.1', '10/Oct/2023:13:55:36 +0800', 'GET', '/api/user', '200', '432')

6. 过滤特殊符号

清理用户输入时,常需要移除特殊字符:

user_input = "重要文件#2023!@需要处理*"
clean = re.sub(r'[^\w\u4e00-\u9fa5]', '', user_input)
print(clean)  # 输出:重要文件2023需要处理

这个正则:

  • [^...]表示取反
  • \w匹配字母数字下划线
  • \u4e00-\u9fa5匹配中文字符

7. 处理多行文本的匹配

当需要跨行匹配时,需要设置re.DOTALL标志:

multiline_text = """Start
这里是正文内容
End"""

match = re.search(r'Start(.*?)End', multiline_text, re.DOTALL)
print(match.group(1))  # 输出换行符和中间内容

性能优化技巧:

  • 对频繁使用的正则进行预编译
phone_re = re.compile(r'\d{11}')
phones = phone_re.findall(text)
  • 避免过度使用.*?这样的贪婪匹配
  • 复杂的正则可以拆分成多个简单正则分步处理

正则表达式真正的价值在于解决实际问题。下次当你面对文本处理需求时,不妨先想想:"这个问题是否能用正则优雅解决?"记住这些实战场景,比死记硬背语法要有用得多。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐