Postgres函数中REGEXP_SPLIT_TO_ARRAY拆分字符串异常求助
解决方案:正确拆分含带空格值的键值对字符串
问题分析
你当前使用的正则E'\\s(?=([^"]*"[^"]*")*[^"]*$)'仅会在偶数个双引号之后的空格处拆分字符串。这就导致未被双引号包裹的键值对(比如KEY_THREE=val three)里的空格会被误判成分隔符,最终该键值对被拆成两个独立元素。
正确正则实现
我们需要调整正则逻辑,只把键值对之间的空格作为分隔符——也就是这个空格必须处于双引号之外,且后面紧跟着一个合法的键名(符合[a-zA-Z_][a-zA-Z0-9_]*=格式)。修改后的代码如下:
myarray := REGEXP_SPLIT_TO_ARRAY(mystring, E'\\s+(?=(?:[^"]*"[^"]*")*[^"]*$)(?=[a-zA-Z_][a-zA-Z0-9_]*=)');
正则规则解释
\\s+:匹配一个或多个连续空格,作为潜在的分隔符(?=(?:[^"]*"[^"]*")*[^"]*$):正向预查,确保当前位置处于双引号之外(即前面的双引号总数为偶数)(?=[a-zA-Z_][a-zA-Z0-9_]*=):正向预查,确保空格后紧跟合法键名(以字母/下划线开头,后跟字母/数字/下划线,最后以等号结尾)
通过这两个预查的组合,就能精准区分:
- 键值对之间的空格:满足"引号外+后接新键名"条件 → 作为分隔符
- 值内的空格:要么在引号内,要么后接内容不是新键名 → 不拆分
测试验证
用你的示例字符串测试:
SELECT REGEXP_SPLIT_TO_ARRAY('keyone="valone" key_two="val two" KEY_THREE=val three keyfour="http://sample.domain?par1=val1&par2=val2" keyFIVE=valfive keysix="sample text par1=val6"', E'\\s+(?=(?:[^"]*"[^"]*")*[^"]*$)(?=[a-zA-Z_][a-zA-Z0-9_]*=)');
输出结果完全符合你的期望:
{keyone="valone",key_two="val two",KEY_THREE=val three,keyfour="http://sample.domain?par1=val1&par2=val2",keyFIVE=valfive,keysix="sample text par1=val6"}
适配调整说明
如果你的键名包含其他特殊字符(比如连字符-),可以修改键名匹配规则,例如将[a-zA-Z_][a-zA-Z0-9_]*替换为[a-zA-Z_-][a-zA-Z0-9_-]*,按需适配业务中的键名格式。
内容的提问来源于stack exchange,提问作者Reza
相关产品推荐
相关产品推荐

