如何编写正则单次提取多格式文本中的价格数值(适配JS/n8n)
问题场景
需要从混杂商品编号、货币符号、不同币种标识的文本中,单次精准提取格式为93.00的两位小数价格数值,货币符号单独走其他正则提取,运行环境为n8n(底层兼容JavaScript正则方言)。
待匹配测试文本
Item price: £93.00 Item number: 265722305071 Item number: 265722305071 Item price: $93.00 £93.00£93.00 265722305071£93.00 foo 265722305071-93.00EURO
已尝试的无效正则
/^(\d*([.,](?=\d{3}))?\d+)+((?!\2)[.,]\d\d)?$/ /^£?[1-9]{1,3}(,\d{3})*(\.\d{2})?$/ /^£?(([1-9]{1,3}(,\d{3})*(\.\d{2})?)|(0\.[1-9]\d)|(0\.0[1-9]))$/ /^\xA3?\d{1,3}?([,]\d{3}|\d)*?([.]\d{1,2})?$/ /^\$?[0-9][0-9,]*[0-9]\.?[0-9]{0,2}$/i (?=.*?\d)^\$?(([1-9]\d{0,2}(,\d{3})*)|\d+)?(\.\d{1,2})?$ /(?=.)^\$?(([1-9][0-9]{0,2}(,[0-9]{3})*)|0)?(\.[0-9]{1,2})?$/ [0-9]+\.[0-9][0-9](?:[^0-9a-zA-Z\s\S\D]|$) ^\d+\.\d{2}$
解决方案
之前写的正则几乎都带了^起始锚点,只能匹配整行完全符合规则的内容,没法从长文本里截取子串,也没有规避长数字(比如11位商品编号)的误匹配问题。
直接用下面这个JS兼容正则即可,单次匹配就能拿到目标值:
(?<!\d)\d{1,3}(?:,\d{3})*\.\d{2}(?!\d)
- 规则说明:
(?<!\d):负向后行断言,保证匹配内容前面不是数字,直接过滤掉11位商品编号里的数字片段\d{1,3}(?:,\d{3})*:兼容千分位格式的价格整数部分,1,293.00这类格式也能正常匹配\.\d{2}:固定匹配小数点后两位的价格小数部分(?!\d):负向先行断言,保证匹配内容后面不是数字,避免截断长数字
针对给出的所有测试用例,这个正则第一次匹配到的结果就是93.00,不会把商品编号、重复拼接的价格误判,也不需要提前处理货币符号、前后缀文本。
如果n8n环境不支持零宽断言(极少概率),可以用这个兼容版:
(?:^|[^0-9])(\d{1,3}(?:,\d{3})*\.\d{2})(?:[^0-9]|$)
取第一个捕获组的内容即可,效果完全一致。
内容的提问来源于stack exchange,提问作者binvius
相关产品推荐
相关产品推荐

