You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用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:结尾可能是多种单位/数量词(比如EachUnitPCS

如果发票里的行项目结尾有多种类似单词,可以用非捕获组扩展:

(?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

火山引擎 最新活动