
本文介绍如何使用 python 正则表达式,从混杂的报关单文本中准确提取每个 hs 编码(如 `hs code: 84732:100`)**之前紧邻的非空描述片段**,自动排除编码本身及干扰字段,支持多种拼写变体(如 `h.s. code`、`hs code`、`hs.code` 等)。
在外贸单证、报关数据或物流文本解析场景中,常需从非结构化字符串中提取商品描述信息——这些描述通常位于 HS CODE(协调制度编码)之前,但前后夹杂发票号、规格、单位等干扰内容。例如:
...FIT-2401-01 HS CODE: 84732:100 KNITTED FABRIC H.S CODE: 6006.2:2.00...
目标是提取出 FIT-2401-01、KNITTED FABRIC、WOVEN TWILL CAP 等语义完整的前置描述,而非包含 HS CODE 的整段文本。
✅ 推荐正则方案(通用健壮版)
使用以下正则表达式可覆盖常见 HS 编码标识变体(大小写不敏感、支持点号/空格/冒号省略):
import re txt = '''293 PACKAGE(S)x000D PRINTED HEAD ITEM: KA02033-E844 A5 :INVOICE: FIT-2401-01 HS CODE: 84732:100 KNITTED FABRIC H.S CODE: 6006.2:2.00 INV#: TSTEX0124-009 (TC-240021:) WOVEN TWILL CAP HS.CODE: 6505.00:.90 KNITTED FABRIC HS 600410 FABRIC: P57101 (T989, 100% POLYESTER, WIDT:H 152CM) HS CODE : 54075200_x000D_ (*)EMA:IL:[email protected] USCI:913101141:32276439L (**)USCI: Container DRYU9124108: 13 PACKAGE(S), AUTOMATIC TOOTH TURNING MACHINESD-CYJ500-1000 HS CODE:84597010; ''' # 核心正则:匹配「非空开头 + 任意字符(非贪婪)」直到遇到 HS 编码模式 pattern = r'(\S.*?)\s+H\.?S\b\.?(?:\s*CODE)?\s*:?\s*\S+' matches = re.findall(pattern, txt, re.IGNORECASE | re.DOTALL) print([s.strip() for s in matches]) # 输出: # ['293 PACKAGE(S)x000D PRINTED HEAD ITEM: KA02033-E844 A5 :INVOICE: FIT-2401-01', # 'KNITTED FABRIC', # 'WOVEN TWILL CAP', # 'KNITTED FABRIC', # 'FABRIC: P57101 (T989, 100% POLYESTER, WIDT:H 152CM)', # 'Container DRYU9124108: 13 PACKAGE(S), AUTOMATIC TOOTH TURNING MACHINESD-CYJ500-1000']
? 正则解析:
- (\S.*?):捕获组,匹配以非空白字符开头、尽可能短的任意内容(含换行);
- \s+:匹配 HS 编码前的空白分隔(1个以上空格/换行);
- H\.?S\b:匹配 H S、HS 或 H.S(\b 确保 HS 不被 HSCODE 中的 HS 错误截断);
- \.?(?:\s*CODE)?:可选的点号 + 可选的 CODE(允许空格);
- \s*:?\s*\S+:可选冒号 + 空格 + 后续编码主体(如 84732:100)。
⚠️ 注意事项与增强建议
- 避免过度匹配:原始尝试 (?=hs code:\s*\d*) 使用先行断言,但未排除已匹配到的 HS CODE 字符串,导致结果包含冗余前缀。本方案通过显式匹配并丢弃编码部分,确保只捕获纯描述。
-
特殊字段处理(如 INV#:):若需从 INV#: TSTEX0124-009 (TC-240021:) WOVEN TWILL CAP 中精准提取 WOVEN TWILL CAP(跳过 INV#: 后的两段乱码),可启用增强模式:
pattern_enhanced = r'(?:INV#:\s*\S+\s+\S+\s+)?(\S.*?)\s+H\.?S\b\.?(?:\s*CODE)?\s*:?\s*\S+'
此模式将 INV#: 及其后两个单词作为可选前缀忽略,再捕获后续描述。
- 边界处理:若文本末尾无 HS 编码,该正则不会匹配结尾残留内容;如需捕获“最后无编码的尾部”,应额外补充 r'(\S.*?)(?=\s+H\.?S\b|$)' 并去重合并。
- 编码清洗:实际业务中,建议对结果做 .strip() 和空白规范化(如 re.sub(r'\s+', ' ', s)),提升后续 NLP 或入库质量。
掌握此正则逻辑,即可高效支撑报关单解析、BOM 提取、海关数据清洗等自动化任务——无需依赖固定格式,真正适配真实世界中的文本噪声。










