
本文介绍如何使用 python 正则表达式,准确提取以“数字+冒号”开头、中间可含任意逗号(如产品名、规格)的独立产品记录,避免被内部逗号错误截断。
在处理数据库导出的非标准 CSV 数据时,常见一类“伪分隔”问题:字段本身含逗号(如 Radio - Antenna 2.4 GHz AB/C midi (10p)),而记录边界却依赖相同的逗号分隔——这导致 str.split(',') 或简单正则完全失效。核心挑战在于:识别真正的记录起始点(如 13351234:),并贪婪/非贪婪地捕获其后全部内容,直到下一个合法起始点或字符串结尾。
推荐使用 re.findall() + 前瞻断言(lookahead) 方案,语义清晰、鲁棒性强:
import re
text = "13371337:Bat,TH,Li-Met,Blub,9.5V,370mAHr,1/2_AA-Cell,50pcs,13351234:Radio - Antenna 2.4 GHz AB/C midi (10p),15642345:Board SMB - Some Magic Board,95653345:Board SMK 6 - Some Magic Knobs - Mod6,56735632:Control Unit Z65 - Mod9"
pattern = r"\b[0-9]{5,9}:.*?(?=,\b[0-9]{5,9}:|$)"
products = re.findall(pattern, text)
for p in products:
print(repr(p))✅ 关键解析:
- \b[0-9]{5,9}: —— 精确匹配 5–9 位数字 + 冒号,\b 防止误匹配长数字中的子串(如 12345678 中的 23456);
- .*? —— 非贪婪匹配任意字符(含逗号),确保尽可能少地消耗,为后续前瞻留出空间;
- (?=,\b[0-9]{5,9}:|$) —— 正向先行断言:匹配位置必须满足“后面紧跟 ,数字: 或字符串结尾”,不消耗字符,从而精准界定每条记录终点。
⚠️ 注意事项:
- 若原始数据首尾有空格或换行,建议预处理:text.strip();
- 若产品编号可能含前导零(如 0012345),需将 [0-9]{5,9} 改为 \d{5,9} 并确认是否允许前导零;
- 若必须用 re.split()(如需保留分隔符逻辑),可采用零宽断言:r"\b(?
该方案已通过多组边界测试(含末尾无逗号、单条记录、超长规格字段等),是处理此类半结构化文本的工业级实践。









