Redshift中regexp_replace正则替换无法移除反斜杠问题咨询
问题原因
这个问题是两层转义规则叠加导致的,和正则[^A-Z]+本身的匹配逻辑无关:
- 第一层是Redshift的SQL字符串解析规则:默认配置下Redshift兼容旧版PostgreSQL的转义逻辑,字符串中的单个反斜杠
\属于转义符,而非普通字符。你写的输入字符串'Abc\Zyxcz\'里,反斜杠出现在不同位置的解析结果完全不同:- 中间位置的
\Z:因为Z不是Redshift预定义的转义字符(支持的转义字符仅包括\n、\'、\\、\t等有限几个),解析器会直接把这部分识别为「反斜杠+大写字母Z」两个普通字符。 - 末尾位置的
\':紧接在反斜杠后面的是字符串结束标记单引号,解析器会优先把这组识别为「转义后的单引号」,但因为这已经是语句末尾,解析器最终会将末尾的反斜杠判定为孤立的普通字符,不会和单引号做转义绑定。
- 中间位置的
- 第二层是正则引擎的解析规则:Redshift的正则函数采用PCRE兼容的转义逻辑,反斜杠同样是正则转义符。正则引擎扫描字符时,会默认认为反斜杠后面需要跟特定字符组成转义序列:
- 中间的反斜杠后面跟着Z,会被识别为独立的普通反斜杠字符,属于非大写字母,因此被
[^A-Z]+匹配替换。 - 末尾的反斜杠后面没有任何字符,属于未完成的转义标记,正则引擎不会把它当成普通字符纳入字符类
[^A-Z]的匹配范围,因此最终残留在返回结果里。
- 中间的反斜杠后面跟着Z,会被识别为独立的普通反斜杠字符,属于非大写字母,因此被
修复方案
涉及反斜杠的场景统一做双重转义即可,不用纠结当前会话的参数配置,直接把字符串里所有字面反斜杠替换成双反斜杠\\:
select regexp_replace(upper('Abc\\Zyxcz\\'),'[^A-Z]+', '');
执行后会返回预期的纯大写字符串ABCZYXCZ,所有反斜杠都会被清除。
如果需要确认当前会话的字符串转义规则,可以执行以下语句查看参数:
show standard_conforming_strings;
- 返回
off时,SQL解析器默认将反斜杠识别为转义符,必须用双反斜杠表示字面反斜杠 - 返回
on时,SQL层按标准规则将单个反斜杠识别为普通字符,但正则层依然会解析反斜杠转义,因此统一写双反斜杠是兼容性最高的写法
内容的提问来源于stack exchange,提问作者Gayathri
相关产品推荐
相关产品推荐

