Redshift中移除数字与非数字间空白失败问题排查
移除数字与非数字间空白的正则表达式失效问题
需求说明
需要移除药物成分字段中数字与非数字之间的空白,示例如下:
原字段值:
CLORIDRATO DE TRAMADOL 37.5 MG E PARACETAMOL 325 MG ATEZOLIZUMABE 1.200 MG ATENOLOL 25 MG DUPILUMABE 175 MG/ML CLORETO DE SODIO 2.34 MG/ML E CLORETO DE POTASSIO 1.49 MG/ML E CITRATO DE SODIO 1.96 MG/ML E GLICOSE 19.83 MG/ML
期望结果:
CLORIDRATO DE TRAMADOL 37.5MG E PARACETAMOL 325MG ATEZOLIZUMABE 1.200MG ATENOLOL 25MG DUPILUMABE 175MG/ML CLORETO DE SODIO 2.34MG/ML E CLORETO DE POTASSIO 1.49MG/ML E CITRATO DE SODIO 1.96MG/ML E GLICOSE 19.83MG/ML
问题原因
你使用的正则表达式(\d+)\s(\D)无法生效,核心问题如下:
- 匹配范围不全:
\d+只能匹配连续的纯数字,无法识别带小数点的数字(比如37.5)。以37.5 MG为例,\d+会匹配37,但后面的.不属于数字字符,导致整个正则无法匹配到37.5和MG之间的空格。 - 未覆盖全局替换(部分SQL方言):部分SQL实现中,
regexp_replace默认只替换第一个匹配项,但这不是当前无效果的主要原因,主因还是正则的匹配逻辑错误。
解决方案
修改正则表达式,使其能匹配包含可选小数部分的数字,再匹配后续空格和非数字字符,同时确保全局替换(按需添加标志):
通用SQL语句
regexp_replace(medication_component, '(\d+(?:\.\d+)?)\s([^\d\s])', '$1$2', 'g') as new_medication_component
正则规则解释
(\d+(?:\.\d+)?):匹配整数或带小数的数字,(?:\.\d+)?是可选的非捕获组,用来匹配小数部分(比如.5、.200)。\s:精准匹配数字与非数字之间的空白字符。([^\d\s]):匹配非数字且非空白的目标字符(比如M、/)。'g':全局替换标志(PostgreSQL等方言需要显式添加,MySQL默认全局替换可省略)。
场景简化版
如果你的非数字部分仅包含大写字母和/,可以进一步简化正则:
regexp_replace(medication_component, '(\d+\.?\d*)\s([A-Z/])', '$1$2', 'g') as new_medication_component
内容的提问来源于stack exchange,提问作者Mariana
相关产品推荐
相关产品推荐

