别死记硬背了!用这7个真实数据清洗场景,彻底搞懂Python正则表达式
·
别死记硬背了!用这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)
- 避免过度使用
.*?这样的贪婪匹配 - 复杂的正则可以拆分成多个简单正则分步处理
正则表达式真正的价值在于解决实际问题。下次当你面对文本处理需求时,不妨先想想:"这个问题是否能用正则优雅解决?"记住这些实战场景,比死记硬背语法要有用得多。
更多推荐



所有评论(0)