使用invoice2data库时,Python正则捕获特定格式商品描述的技术需求
解决invoice2data中提取带非字母字符的行项目描述问题
我来帮你搞定这个正则表达式的问题!从你的例子和需求来看,你之前用的(?P<descr>(\w+\s)+)之所以失效,核心问题有两个:一是\w只能匹配字母、数字和下划线,没法覆盖像/这种非字母字符;二是没有处理排除最后一个单词(比如Each)的逻辑。
针对需求的正则方案
这里给你几个实用的正则表达式,适配不同的场景:
场景1:明确知道结尾是特定单词(比如Each)
这个方案用非贪婪匹配+结尾锚定,精准捕获到最后一个目标单词之前的内容:
(?P<descr>.+?)\s+Each$
- 细节解释:
(?P<descr>.+?):命名捕获组,用非贪婪模式匹配任意字符(除换行),直到后面的条件触发,避免过度匹配到不需要的内容。\s+Each$:匹配一个或多个空格,然后是Each,并且锚定到字符串结尾($),确保Each是最后一个单词。
测试你的示例字符串HOSE 1/4 X BSP F 3/8 Each,会精准提取出HOSE 1/4 X BSP F 3/8。
场景2:结尾可能是多种单位/数量词(比如Each、Unit、PCS)
如果发票里的行项目结尾有多种类似单词,可以用非捕获组扩展:
(?P<descr>.+?)\s+(?:Each|Unit|PCS|EA)$
- 细节解释:
(?:Each|Unit|PCS|EA)是一个非捕获组,用来匹配任意指定的结尾单词,你可以根据实际发票里的词汇随时添加或修改。
场景3:需要严格匹配每个“单词”的字符范围(仅允许字母、数字、/)
如果要确保捕获的每个部分只包含指定字符(避免意外匹配其他特殊符号),可以用字符集来定义“单词”:
(?P<descr>(?:[a-zA-Z0-9/]+(?:\s))+)(?=\s+(?:Each|Unit))
- 细节解释:
[a-zA-Z0-9/]+:仅匹配字母、数字和/组成的“单词”,如果需要支持其他字符(比如-),直接添加到字符集里即可,比如[a-zA-Z0-9/-]+。(?=\s+(?:Each|Unit)):正向预查,确保后面跟着空格和指定结尾词,不会把结尾词包含到捕获结果里。
在invoice2data中的使用示例
把正则放到你的YAML模板配置里就行,比如:
fields: description: regex: '(?P<description>.+?)\s+(?:Each|Unit)$' type: text
快速验证代码
用Python代码可以快速测试效果:
import re test_texts = [ "HOSE 1/4 X BSP F 3/8 Each", "WRENCH 10mm Unit", "PIPE 2-1/2 PCS" ] pattern = r'(?P<descr>.+?)\s+(?:Each|Unit|PCS)$' for text in test_texts: match = re.search(pattern, text) if match: print(f"原字符串: {text}") print(f"提取结果: {match.group('descr')}\n")
运行后会输出:
原字符串: HOSE 1/4 X BSP F 3/8 Each 提取结果: HOSE 1/4 X BSP F 3/8 原字符串: WRENCH 10mm Unit 提取结果: WRENCH 10mm 原字符串: PIPE 2-1/2 PCS 提取结果: PIPE 2-1/2
内容的提问来源于stack exchange,提问作者West




