新闻中心
Python教程:定制化解析复杂空格分隔文本并生成CSV

当面对格式不规范、空格分隔的文本文件时,标准的数据导入库如pandas可能无法有效处理。本教程将指导您如何利用python和正则表达式,通过定制化的解析逻辑,识别并区分字段分隔符与数据内部的空格,从而成功地将此类“脏数据”转换为结构化的csv文件。
在数据处理的实践中,我们经常会遇到格式不规范的文本文件。这类文件通常使用不规则数量的空格来分隔字段,甚至在数据字段内部也可能包含空格,这使得传统的 pandas.read_csv 等方法难以直接处理。例如,尝试使用制表符 (sep='\t') 或固定数量空格 (sep=r"\s{2,}") 作为分隔符,往往会导致列错位、数据丢失或解析错误。为了有效地将这类“坏”文本文件转换为结构化的CSV格式,我们需要编写自定义的Python解析逻辑。
理解“坏”文本文件的挑战
问题中提供的文本数据示例很好地说明了这类文件带来的挑战:
- 不一致的空格长度: 不同字段之间分隔的空格数量不固定,这使得无法简单地通过固定宽度或统一的分隔符进行分割。
- 数据内部的空格: 某些字段(例如 Message 字段)本身包含两个或更多连续的空格(如“Rejected at level”中的“at”和“level”之间),这极易与字段分隔符混淆,导致错误的列分割。
- 空行: 文件中可能包含空行,需要被正确识别和忽略。
- 缺失值: 某些字段可能为空,表现为连续的多个空格,其长度可能与字段分隔符的长度相似。
定制化解析方案:Python与正则表达式
针对这类复杂场景,最有效的方法是采用逐行读取文件,并结合正则表达式进行精细化匹配和替换的策略。核心思想是:识别不同长度的连续空格所代表的含义——究竟是字段分隔符,还是数据本身的一部分。
Musho
AI网页设计Figma插件
76
查看详情
以下是实现这一目标的核心Python代码,并附带详细解释:
import re
import csv
def parse_bad_txt_to_table(filepath):
"""
解析不规范的空格分隔文本文件,并将其转换为一个列表的列表(表格形式)。
Args:
filepath (str): 待解析的文本文件路径。
Returns:
list[list[str]]: 解析后的数据表格,每个内部列表代表一行。
"""
table = []
try:
with open(filepath, 'r', encoding='utf-8') as f:
lines = f.readlines()
except FileNotFoundError:
print(f"错误:文件 '{filepath}' 未找到。")
return []
except Exception as e:
print(f"读取文件时发生错误:{e}")
return []
for i, line in enumerate(lines):
line = line.rstrip('\n') # 移除行尾的换行符
if i == 0:
# 第一行:标题行。假设标题字段之间不会有“假分隔符”,
# 故可以安全地按2个或更多空格分割。
row = re.split(r' {2,}', line)
table.append(row)
continue
if not line.strip(): # 检查是否为空行(包括只含空格的行)
# 忽略空行,或者根据需要进行特定处理
continue
# 对于数据行,我们需要更复杂的逻辑来区分字段分隔符和数据内部的空格
def replfunc(match_obj):
"""
根据匹配到的连续空格的长度,决定是替换为单个空格(数据内部)
还是一个或多个制表符(字段分隔符)。
"""
L = len(match_obj.group(0)) # 获取匹配到的连续空格的长度
# 特殊情况处理:识别数据内部的特定空格模式。
# 示例中 "Rejected at level." 内部有2个空格,这不应被视为分隔符。
start, end = match_obj.span()
if L == 2 and line[:start].endswith('Rejected at') and line[end:].startswith('level.'):
return ' ' # 将其替换为单个空格,保留在数据内部
# 其他连续空格被视为字段分隔符,根据其长度映射为不同数量的制表符。
# 这里的映射规则需要根据实际数据进行观察、分析和调整。
if L < 2:
# 理论上不应出现少于2个空格被视为分隔符的情况,否则与数据内部空格冲突。
# 如果出现,保持不变或抛出警告。
return match_obj.group(0)
elif 2 <= L <= 12: # 2到12个空格,替换为单个制表符
return '\t'
elif L == 17: # 17个空格,替换为两个制表符(表示中间可能存在一个空字段)
return '\t\t'
elif L == 43: # 43个空格,替换为三个制表符
return '\t\t\t'
elif L == 61: # 61个空格,替换为五个制表符
return '\t\t\t\t\t'
elif L == 120 or L == 263: # 其他特定长度的空格,替换为单个制表符
return '\t'
else:
# 如果遇到未预料的空格长度,可以标记出来以便调试和规则完善。
# print(f"警告: 未处理的空格长度 {L} 在行 {i+1}: '{line}'")
return '\t' # 默认替换为单个制表符,可能需要调整
# 使用re.sub结合replfunc替换连续空格,将字段分隔符统一为制表符
tabbed_line = re.sub(r'\s{2,}', replfunc, line)
row = tabbed_line.split('\t') # 依据制表符分割字段
table.append(row)
return table
def write_table_to_csv(table_data, output_filepath):
"""
将解析后的表格数据写入CSV文件。
Args:
table_data (list[list[str]]): 待写入的表格数据。
output_filepath (str): 输出CSV文件的路径。
"""
try:
with open(output_filepath, 'w', newline='', encoding='utf-8') as csvfile:
csv_writer = csv.writer(csvfile)
csv_writer.writerows(table_data)
print(f"数据已成功转换为 '{output_filepath}'")
except Exception as e:
print(f"写入CSV文件时发生错误:{e}")
# --- 示例使用 ---
input_file = 'input.txt' # 假设您的原始文本文件名为input.txt
output_file = 'Report.csv'
# 1. 解析文本文件
parsed_data_table = parse_bad_txt_to_table(input_file)
# 2. 将解析后的数据写入CSV文件
if parsed_data_table:
write_table_to_csv(parsed_data_table, output_file)
# ---------------------------
# 以下代码用于在控制台美观地打印解析结果,便于检查(可选)
def print_formatted_table(table_data):
"""
在控制台以对齐的方式打印表格数据。
"""
if not table_data:
print("无数据可显示。")
return
# 计算每列的最大宽度
max_n_fields = max(len(row) for row in table_data)
field_widths = [0] * max_n_fields
for row in table_data:
for j, field in enumerate(row):
if j < max_n_fields:
field_widths[j] = max(field_widths[j], len(field))
# 打印表格
for row in table_data:
for j, field in enumerate(row):
if j < max_n_fields:
print(field.ljust(field_widths[j]), end='|')
print()
# print("\n解析结果预览:")
# print_formatted_table(parsed_data_table)代码解析与注意事项
- 逐行处理: 文件被逐行读取,这允许我们根据行号(例如,标题行与数据行)应用不同的解析规则。rstrip('\n') 用于移除行尾的换行符。
- replfunc 的核心作用: 这是整个解析逻辑的关键。re.sub(r'\s{2,}', replfunc, line) 会查找所有连续两个或更多空格的序列 (\s{2,}),并对每个匹配项调用 replfunc 函数。
- 区分数据内部空格与分隔符: replfunc 首先检查一个特定的模式("Rejected at level."),如果匹配,则将两个空格替换为单个空格,从而保留其作为数据的一部分。这种模式识别是针对特定业务逻辑的定制化处理,对于不同的文件,需要根据实际情况调整。
- 动态映射空格长度到制表符: 对于其他连续空格,replfunc 根据其长度将其替换为一个或多个制表符 (\t)。例如,如果 L 是 17,它被替换为两个制表符,这暗示了在原始文本中可能存在一个空字段。这些映射规则 (L == 17 对应 \t\t 等) 是通过观察原始数据中不同字段分隔符的宽度总结出来的,并且可能需要根据实际文件的具体情况进行微调。这是最需要人工分析和调整的部分。
- split('\t'): 一旦所有字段分隔符都被统一替换为制表符,就可以简单地使用 split('\t') 来获取最终的字段列表。
- CSV写入: 使用Python内置的 csv 模块将解析后的数据写入CSV文件。newline='' 参数在 open() 中是重要的,它能防止在Windows系统上写入额外的空行。
- 通用性限制: 这种方法高度依赖于对特定“坏”文件格式的观察和理解。如果文件格式稍有变化,replfunc 中的逻辑(特别是空格长度的映射)可能需要重新调整。对于高度不规则的文件,甚至可能需要更复杂的有限状态机或机器学习方法来自动识别模式。
- 错误处理: 示例代码中包含文件读取和写入的 try-except 块,以提高程序的健壮性。replfunc 中的 else 分支可以用于处理未预期的空格长度,这对于调试和发现新的格式模式非常有用。
总结
处理格式不规范的文本文件是一项常见的挑战,尤其当标准库无法直接胜任时。通过Python结合正则表达式的定制化解析,我们可以精确控制如何识别和处理字段分隔符,即使在数据内部存在与分隔符相似的模式。虽然这种方法需要根据具体文件格式进行细致的调整和测试,但它为解决复杂的数据清洗问题提供了一个强大而灵活的工具。在实际应用中,建议对数据进行充分的探索性分析,以建立准确的解析规则,并考虑将解析逻辑模块化,以便于维护和复用。
以上就是Python教程:定制化解析复杂空格分隔文本并生成CSV的详细内容,更多请关注其它相关文章!
# 多个
# seo简历英语
# 北京seo整合营销
# 宁波江北区网站推广定制
# 361推广网站
# 建设学校的网站有什么用
# 未优化的seo
# seo到底需要怎么做
# 好用的线上商城网站推广
# 内江SEO鱼刺系统
# 企业文库营销推广
# 将其
# 这是
# 自定义
# 不规范
# python
# 转换为
# 这类
# 文本文件
# 分隔符
# 数据丢
# csv文件
# windows系统
# 数据清洗
# win
# csv
# 工具
# app
# windows
# 正则表达式
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Golang指针如何与map组合使用_Golang map指针组合实践
新手怎么开始学化妆 零基础化妆入门教程
html5 app怎么运行环境_配html5 app运行环境【教程】
vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧
钉钉视频会议画面卡顿如何解决 钉钉会议画面优化方法
CSS响应式网页如何实现主次模块比例自适应_flex-grow与flex-shrink调整
TypeScript/J*aScript:高效查找数组中首个唯一ID对象
J*aScript实现单选按钮与关联输入框的联动禁用教程
Golang如何实现容器化日志收集与分析_Golang容器日志收集分析方法
ArchiveofOurOwn小说阅读-ArchiveofOurOwn同人作品访问链接
深入理解Go语言中Map值与方法接收器的交互:为什么需要临时变量
HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全
如何在Promise链中有效终止错误处理后的执行
微信网页版官方快速登录入口 微信网页版网页版账号直达
支付宝碰一碰设备是REDMI手机吗 博主拆机辟谣:处理器、内存都不一样
2026春节假期票务安排_2026春节放假购票指南
腾讯QQ邮箱登录入口_QQ邮箱官方网站使用地址
Mac怎么查看崩溃日志_Mac控制台错误报告分析
谷歌浏览器最新官方入口链接 谷歌浏览器网页版官网导航
Promise错误处理:在catch后终止链式then执行的策略
Python实现多节点属性重叠度分析教程
Win11如何开启讲述人功能 Win11屏幕阅读器(讲述人)开启与关闭【教程】
Golang如何实现Web文件静态资源服务器_Golang静态资源服务器开发与实践
AO3最新可访问网址 Archive of Our Own官方在线入口
响应式图片在网页设计中的正确实现方法
Pandas DataFrame 多条件优先级排序与排名
Win11怎么设置鼠标指针速度_Win11提高鼠标指针精确度选项
J*aScript中针对特定容器内图片动画的实现教程
QQ邮箱官方网站登录入口_QQ邮箱网页版在线使用
提升屏幕阅读器对“m”时间单位的播报准确性:HTML与CSS组合解决方案
小猿搜题在线学习页面在哪_小猿搜题在线学习中心入口
圆通快递查询实时追踪 圆通物流包裹状态快速查看
优化Log4j2控制台输出性能:解决异步日志瓶颈
qq游戏网页版直接玩_qq游戏免下载快速入口
Golang如何使用const iota_Go iota常量计数器讲解
一加 14R 快充无反应_一加 14R 充电优化
windows10怎么查看本机ip_windows10命令提示符ipconfig使用
win11如何卸载Windows更新补丁 Win11解决更新导致系统不稳定的问题【修复】
铁路12306官网网页端快速入口 铁路12306官方首页登录教程
漫蛙2在线漫画入口 漫蛙正版漫画网页版直达
谷歌浏览器怎么给标签页静音_Chrome标签静音快捷操作
黑鲨3Pro怎样在相册开漫画风滤镜_iPhone黑鲨3Pro相册开漫画风滤镜【趣味滤镜】
J*aScriptWebpack优化_J*aScript构建工具实战
包子漫画官方网站阅读入口-包子漫画在线漫画官网直达链接
抖音网页版怎么|直播|_抖音网页版开播操作指南
c++如何使用折叠表达式(Fold Expressions)_c++17可变参数模板新技巧
抓大鹅解压小游戏 抓大鹅摸鱼解压入口
LINUX怎么设置定时任务_LINUX crontab配置教程
css元素hover动画延迟生效怎么办_使用animation-delay调整触发时间
c++如何实现一个简单的软件渲染器_c++从零开始的3D图形学


2025-10-31
浏览次数:次
返回列表
output_filepath (str): 输出CSV文件的路径。
"""
try:
with open(output_filepath, 'w', newline='', encoding='utf-8') as csvfile:
csv_writer = csv.writer(csvfile)
csv_writer.writerows(table_data)
print(f"数据已成功转换为 '{output_filepath}'")
except Exception as e:
print(f"写入CSV文件时发生错误:{e}")
# --- 示例使用 ---
input_file = 'input.txt' # 假设您的原始文本文件名为input.txt
output_file = 'Report.csv'
# 1. 解析文本文件
parsed_data_table = parse_bad_txt_to_table(input_file)
# 2. 将解析后的数据写入CSV文件
if parsed_data_table:
write_table_to_csv(parsed_data_table, output_file)
# ---------------------------
# 以下代码用于在控制台美观地打印解析结果,便于检查(可选)
def print_formatted_table(table_data):
"""
在控制台以对齐的方式打印表格数据。
"""
if not table_data:
print("无数据可显示。")
return
# 计算每列的最大宽度
max_n_fields = max(len(row) for row in table_data)
field_widths = [0] * max_n_fields
for row in table_data:
for j, field in enumerate(row):
if j < max_n_fields:
field_widths[j] = max(field_widths[j], len(field))
# 打印表格
for row in table_data:
for j, field in enumerate(row):
if j < max_n_fields:
print(field.ljust(field_widths[j]), end='|')
print()
# print("\n解析结果预览:")
# print_formatted_table(parsed_data_table)