使用Python与正则表达式高效提取Excel中的票号数据
一、需求
本文将介绍如何利用Python的Pandas库和正则表达式,快速实现票号这一数据清洗任务,并将结果整理为规范的表格结构。
在数据处理场景中,从非结构化文本里提取特定格式的信息是常见需求。例如在物流工单、票务系统的Excel记录中,我们经常需要从冗长的摘要文本里提取出票号(如快递单号、订单号等)。
二、核心代码解析
我们通过一段实际代码来演示整个处理流程,代码逻辑分为数据读取、正则匹配、结果整理三个核心步骤。
1. 导入依赖库
import pandas as pd
import re
pandas
:用于Excel文件的读写和数据处理re
:正则表达式模块,用于文本模式匹配
2. 读取原始数据
df = pd.read_excel('报销.xlsx')
- 使用
pd.read_excel
读取原始Excel文件,假设数据存储在默认的第一个工作表 - 原始数据结构:假设第一列为包含票号的摘要文本(如“处理票号1234567890的问题”)
3. 预编译正则表达式
ticket_pattern = re.compile(r'\b\d{8,30}\b')
- 模式解析:
\b
:单词边界,确保匹配独立数字串\d{8,30}
:匹配8到30位的连续数字(可根据实际票号长度调整)
- 预编译优势:避免重复编译正则表达式,提升匹配性能
4. 遍历文本并提取票号
result_data = []
for text in df.iloc[:, 0].astype(str):
tickets = ticket_pattern.findall(text)
if tickets:
# 处理第一条记录(包含摘要和首个票号)
result_data.append({'摘要': text, '票号': tickets[0]})
# 处理剩余票号(摘要留空)
result_data.extend({'摘要': '', '票号': ticket} for ticket in tickets[1:])
else:
# 无票号时保留摘要
result_data.append({'摘要': text, '票号': ''})
- 关键逻辑:
df.iloc[:, 0]
:选取第一列数据(假设票号在第一列)astype(str)
:确保所有数据转为字符串类型,避免类型错误findall
方法:返回所有匹配的票号列表- 数据结构设计:
- 首个票号保留对应的摘要文本
- 后续票号共享同一摘要(摘要留空以节省空间)
- 无票号记录保留原始摘要,票号字段为空
5. 保存结果到Excel
pd.DataFrame(result_data).to_excel('output4.xlsx', index=False)
- 将结果列表转换为DataFrame并保存为新Excel文件
index=False
参数:禁止生成默认行索引列
三、技术关键点
1. 正则表达式优化技巧
- 动态调整匹配模式:若票号包含字母(如“YT123456”),可修改模式为:
r'\b[A-Za-z0-9]{8,30}\b' # 匹配字母数字混合字符串
- 边界控制:使用
\b
避免匹配长数字串中的子串(如从“123456789012”中提取完整票号,而非截断部分)
2. Pandas数据处理技巧
- 向量化操作:虽然本例使用循环遍历,对于大规模数据可尝试向量化处理(如
df[0].apply()
)以提升速度 - 数据类型管理:通过
astype(str)
统一处理可能的数值型、日期型数据,避免正则匹配错误
3. 多票号处理逻辑
- 当单条摘要包含多个票号时(如“涉及票号123456和789012”),代码会将首个票号与摘要关联,后续票号以“摘要为空+独立票号”的形式展示,便于后续数据统计。
需要源码的,加同名ggh,进行获取