
本文介绍使用python正则匹配与缓冲读取两种方法,安全去除未加引号csv中字段内部的意外换行符(如描述字段跨行),同时严格保留每条记录末尾的合法换行,确保结构完整性。
本文介绍使用python正则匹配与缓冲读取两种方法,安全去除未加引号csv中字段内部的意外换行符(如描述字段跨行),同时严格保留每条记录末尾的合法换行,确保结构完整性。
在处理来自外部系统的原始文本数据(如~分隔、无引号包裹的类CSV格式)时,一个常见痛点是:业务字段(如description)本身包含换行符(\r\n或\n),导致逻辑上的一行数据被错误切分为多行,破坏后续解析(如csv.reader会报错或错位)。而标准CSV解析器(如csv模块)默认依赖引号界定字段,对无引号且含内嵌换行的场景束手无策。
核心思路是:不依赖逐行分割,而是依据“行首ID + 行尾日期”这一稳定模式识别完整逻辑行。观察示例数据可知,每条有效记录均以数字ID开头(1~, 2~, …),并以MM/DD/YY格式日期结尾(如9/7/67),中间字段(含可能跨行的description)则自由变化。
以下提供两种生产就绪方案:
✅ 方案一:全量读取 + 正则匹配(适合中小文件)
import re
with open('sample.txt', 'r', encoding='utf-8') as f_in:
header = f_in.readline() # 读取首行头(含~分隔符)
content = f_in.read() # 读取全部剩余内容
with open('cleaned.csv', 'w', encoding='utf-8') as f_out:
f_out.write(header.replace('~', ',')) # 头部转为CSV逗号分隔
# 匹配完整逻辑行:ID + 任意内容 + 日期(非贪婪)
pattern = r'\d+~[^~]*~[^~]*~[^~]*~\d{1,2}/\d{1,2}/\d{2}'
for match in re.finditer(pattern, content, re.DOTALL):
line = match.group(0)
# 将行内所有换行符替换为空格(或按需用'\t'/'|'等)
cleaned_line = line.replace('\n', ' ').replace('\r', ' ')
f_out.write(cleaned_line.replace('~', ',') + '\n')
⚠️ 注意事项:
- 正则中的
[^~]*替代.*?更健壮,避免因字段含~导致匹配失败;re.DOTALL确保.能匹配换行符;- 若日期格式不固定(如含年份四位数、空格等),请调整
\d{1,2}/\d{1,2}/\d{2,4};- 此方案假设描述字段内不含
~和日期模式,否则需更复杂状态机。
✅ 方案二:流式缓冲读取(适合大文件,内存友好)
import re
pattern = re.compile(r'^\d+~[^~]*~[^~]*~[^~]*~\d{1,2}/\d{1,2}/\d{2}$', re.MULTILINE)
with open('sample.txt', 'r', encoding='utf-8') as f_in, \
open('cleaned.csv', 'w', encoding='utf-8') as f_out:
header = f_in.readline()
f_out.write(header.replace('~', ','))
buffer = ''
for line in f_in:
buffer += line
# 去除buffer首尾空白后尝试匹配整行
stripped = buffer.strip()
if pattern.match(stripped):
# 替换所有内部换行符,写入并清空buffer
cleaned = stripped.replace('\n', ' ').replace('\r', ' ')
f_out.write(cleaned.replace('~', ',') + '\n')
buffer = ''
# 若未匹配,继续累积(应对长description跨多行)
? 关键设计:
- 使用
^和$锚定整行,配合re.MULTILINE;buffer.strip()消除累积时的多余空白干扰;- 匹配成功后立即清空buffer,避免残留;
- 即使单行
description超长,只要最终满足模式即被正确捕获。
? 总结
- 永远优先验证数据模式:确认ID起始、日期结尾、分隔符一致性;
-
避免盲目
replace('\n', ' '):这会破坏所有行尾换行,导致单行输出; - 生产环境建议添加日志与异常处理:例如记录匹配失败的buffer内容,便于排查边缘case;
- 若数据量极大或模式复杂(如description含日期),应升级为基于状态机的解析器(如
pyparsing)或预处理工具(如awk)。
通过以上任一方法,您均可将原始混乱的多行记录,精准还原为结构清晰、可被标准CSV工具直接消费的单行格式。











