You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何遍历含多商品发票的非结构化TXT并生成Pandas DataFrame

非结构化发票TXT文件的多商品数据提取问题

我有一个包含数百张发票及其对应商品的非结构化TXT文件,每张发票的商品数量为1到10个不等。该TXT文件格式大致如下:

-------REPORT--------
Invoice..: 2000
Product BarCode Price
ASPIRIN
001001
5.00
Total: 5.00
Invoice..: 2001
Product BarCode Price
LOSARTAN
005001
5.00
VITAMIN
002111
10.00
Total: 15.00

大多数发票仅含一个商品,针对这类情况,我使用以下代码可提取全部数据:

import re

invoice = []
product = []
barcode = []
price = []

lines = [line.strip() for line in open('your_invoice_file.txt', 'r') if line.strip()]

for idx, x in enumerate(lines):
    if 'Invoice..:' in x:
        invoice.append(re.search(r'(?<=Invoice..:).*', x).group(0).strip())
    elif 'Product' in x:
        product.append(lines[idx+1])
        barcode.append(lines[idx+2])
        price.append(lines[idx+3])

但我无法解决发票含两个及以上商品时,正确提取商品名称、条形码和价格的问题。最终我希望生成如下结构的Pandas DataFrame:

InvoiceProductBarCodePrice
2000Aspirin0010015.00
2001Losartan0050015.00
2001Vitamin00211110.00

解决方案

核心思路是跟踪当前发票编号,在遇到Product表头后,循环提取后续的商品信息,直到碰到Total行或者下一张发票的开头。

以下是可处理多商品场景的代码:

import re
import pandas as pd

# 读取并清理文本行(去掉空行和首尾空格)
with open('your_invoice_file.txt', 'r') as f:
    lines = [line.strip() for line in f if line.strip()]

data = []
current_invoice = None
i = 0

while i < len(lines):
    line = lines[i]
    # 匹配发票编号
    if 'Invoice..:' in line:
        current_invoice = re.search(r'(?<=Invoice..:).*', line).group(0).strip()
        i += 1
    # 碰到商品表头,开始提取商品
    elif 'Product BarCode Price' in line:
        i += 1  # 跳过表头行
        # 循环提取商品,直到遇到Total或下一张发票
        while i < len(lines) and not lines[i].startswith('Total:') and not 'Invoice..:' in lines[i]:
            # 商品名称、条形码、价格是连续三行
            product_name = lines[i].strip().title()
            barcode = lines[i+1].strip()
            price = lines[i+2].strip()
            # 添加到数据列表
            data.append({
                'Invoice': current_invoice,
                'Product': product_name,
                'BarCode': barcode,
                'Price': price
            })
            i += 3  # 跳过当前商品的三行
    else:
        i += 1  # 跳过其他行(比如Total行)

# 转换为DataFrame
df = pd.DataFrame(data)
print(df)

代码说明:

  1. 清理文本行:先去掉空行和每行的首尾空格,避免干扰匹配
  2. 跟踪当前发票:每次遇到发票编号时,记录当前的发票号,后续商品都关联这个编号
  3. 循环提取商品:碰到商品表头后,连续读取三行作为一个商品的信息,直到碰到Total或者下一张发票的开头,确保多商品能被全部提取
  4. 格式统一:用title()把商品名称转为首字母大写的格式,和期望输出一致

运行后即可得到符合要求的DataFrame。


内容的提问来源于stack exchange,提问作者Leonardo Nascimento

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:43:34