Python 3.10.10银行账单字符串拆分与制表符添加问题求助
银行账单TXT格式化问题及解决方案
问题背景
- 使用Python 3.10.10处理银行账单TXT文件,每行需拆分为7个固定字段:日期、描述、参考编号、交易日期、取款金额、存款金额、期末余额
- 仅描述字段允许包含空格,其余字段无空格
- 3500行数据存在多种格式异常:
- 描述字段内混入随机制表符
- 参考编号前有时缺失制表符分隔
- 存在重复日期(示例:
24/12/2021 24/12/2021 sample description REFNO123456 24/12/2021 0.00 100.00 1000.00) - 部分交易无参考编号,但需保证字段拆分正确
- 账单为加密文档,仅能通过特定库导出为TXT;手动修正效率极低(一周仅完成1000行),现有ChatGPT提供的代码无效
当前使用代码
f=open('/bankinfo final.txt','r') txt=f.readlines() cleanlist=[] finalist=[] for line in txt: for x in line.split(sep=' '): if x!='': cleanlist.append(x) part1=(cleanlist[0]) part2=(' '.join(cleanlist[1:-6])) part3=(' '.join(cleanlist[:-7:-1][::-1])) mashup=part1+'\t'+part2+'\t'.join(part3.split()) finalist.append(mashup) mashup='' cleanlist=[] f.close() f=open('bankinfo parsed.txt','w') f.write('\n'.join(finalist)) f.close()
解决方案
核心思路是通过字段特征(日期、金额、参考编号的格式规则)精准拆分,而非简单按空格分割:
实现代码
import re # 定义正则匹配规则,可根据实际账单格式调整 DATE_PATTERN = re.compile(r'^\d{2}/\d{2}/\d{4}$') # DD/MM/YYYY格式日期 AMOUNT_PATTERN = re.compile(r'^-?\d+\.\d{2}$') # 带两位小数的金额(支持负数) REF_PATTERN = re.compile(r'^REF[A-Z0-9]+$') # 参考编号规则(假设以REF开头) def parse_single_line(line): # 统一所有空白字符为单个空格,去除首尾空白 cleaned_line = re.sub(r'\s+', ' ', line.strip()) if not cleaned_line: return None tokens = cleaned_line.split(' ') # 从后往前定位交易日期和金额字段:找最后一组"日期+3个金额"的组合 transaction_segment_idx = -1 for i in range(len(tokens)-3, 0, -1): if DATE_PATTERN.match(tokens[i]) and all(AMOUNT_PATTERN.match(amt) for amt in tokens[i+1:i+4]): transaction_segment_idx = i break if transaction_segment_idx == -1: return f"INVALID_LINE: {cleaned_line}" # 拆分出交易相关字段 transaction_date, withdrawal, deposit, balance = tokens[transaction_segment_idx:transaction_segment_idx+4] remaining_tokens = tokens[:transaction_segment_idx] # 提取账单日期(第一个符合格式的日期) bill_date = None for idx, token in enumerate(remaining_tokens): if DATE_PATTERN.match(token): bill_date = token middle_tokens = remaining_tokens[idx+1:] break if not bill_date: return f"MISSING_BILL_DATE: {cleaned_line}" # 识别参考编号 ref_no = "" description_tokens = middle_tokens.copy() for idx, token in enumerate(middle_tokens): if REF_PATTERN.match(token): ref_no = token description_tokens = middle_tokens[:idx] break description = ' '.join(description_tokens) # 组装为制表符分隔的结果 return '\t'.join([bill_date, description, ref_no, transaction_date, withdrawal, deposit, balance]) # 批量处理文件 input_file = '/bankinfo final.txt' output_file = 'bankinfo parsed.txt' with open(input_file, 'r', encoding='utf-8') as f_in: lines = f_in.readlines() processed_lines = [] for line_num, line in enumerate(lines, 1): result = parse_single_line(line) processed_lines.append(result if result else f"EMPTY_LINE_{line_num}") with open(output_file, 'w', encoding='utf-8') as f_out: f_out.write('\n'.join(processed_lines))
代码说明
- 预处理:将所有空白字符(空格、制表符)统一为单个空格,消除格式杂乱问题
- 反向定位:从行尾往前找交易日期和金额字段,避免描述内容干扰拆分
- 特征匹配:用正则识别日期、金额、参考编号,确保字段拆分的准确性
- 异常处理:对不符合格式的行标记异常,方便后续人工核对少量特殊情况
内容的提问来源于stack exchange,提问作者DuckSleazzy
相关产品推荐
相关产品推荐

