You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从SQL Server迁移至Postgres:字符有效性校验问题排查

问题分析与解决

你的代码存在两个核心问题,导致Ä这类重音字符未被判定为无效:

1. 逻辑完全颠倒

当前CASE WHEN的条件是匹配不在有效集合内的字符时保留原字符,这与你“保留有效字符、替换无效字符”的需求完全相反。SQL Server的原逻辑应该是仅保留符合规则的字符,而你现在的Postgres代码刚好写反了判断条件。

2. 正则表达式写法错误

  • 你使用similar to的[^...]负向字符类,本意是定义有效字符的排除集,但后续又额外排除[、]、^,逻辑混乱;
  • 字符类中的-没有放在开头或结尾,会被当作范围符号(比如]--"会被解析为从]到"的字符范围),导致正则匹配不符合预期;
  • HTML转义后的引号(")在Postgres中应使用双引号转义(即""),但你的写法冗余且易出错。

修正后的代码

直接使用Postgres的regexp_replace函数可以更高效地实现需求,无需逐字符遍历:

SELECT regexp_replace('ÄZYasdXA', '[^a-zA-Z0-9_{}"() *&%$#@!?/\;:,.—<>–+ =`|~-]', '|', 'g') AS stringagg;

代码说明

  • [^a-zA-Z0-9_{}"() *&%$#@!?/\;:,.—<>–+ =|~-]`:定义无效字符集合(即所有不在有效范围内的字符),其中:
    • a-zA-Z0-9匹配ASCII大小写字母和数字;
    • 后续的特殊字符是你允许的符号,-放在字符类末尾避免被当作范围符号;
  • 'g'参数表示全局替换,将所有无效字符替换为|;
  • 该正则不会匹配Ä这类Unicode重音字符,因此会被替换为|,与SQL Server的行为一致。

如果你坚持要保留原逐字符遍历的写法,修正后的CASE WHEN逻辑如下:

SELECT
  string_agg(txml.substr_text, '') AS stringagg
FROM (
  SELECT
    CASE
      WHEN substring('ÄZYasdXA', n, 1) SIMILAR TO '[a-zA-Z0-9_{}"() *&%$#@!?/\;:,.—<>–+ =`|~-]'
      THEN substring('ÄZYasdXA', n, 1)
      ELSE '|'
    END AS substr_text
  FROM (SELECT * FROM generate_series(1, 1000)) AS nums (n)
  WHERE n <= LENGTH('ÄZYasdXA')
) AS txml;

内容的提问来源于stack exchange,提问作者titan31

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 08:43:16