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

Oracle中如何用•替换单词的一半字符?求助实现方案

实现单词半隐藏的REGEXP_REPLACE解决方案

需求回顾

需要将每个单词的后半部分字符替换为•,规则明确:

  • 计算单词长度,保留前半部分(长度向上取整:比如长度5保留前3位,长度8保留前4位)
  • 示例:question → ques••••,World → wor••,目标字符串Stack Overflow需输出Sta•• Over••••

可行方案

方案1:拆分单词处理后拼接(推荐)

Oracle的REGEXP_REPLACE无法直接在替换逻辑中动态计算单个单词的长度,因此先拆分字符串为独立单词,分别处理后再拼接是最清晰的方案:

SELECT 
  LISTAGG(
    -- 保留前半部分 + 生成对应数量的•
    SUBSTR(word, 1, CEIL(LENGTH(word)/2)) || RPAD('', FLOOR(LENGTH(word)/2), '•'),
    ' '
  ) WITHIN GROUP (ORDER BY pos) AS masked_text
FROM 
  XMLTABLE(
    -- 按空格拆分字符串,记录单词位置保证顺序
    'for $i in tokenize(., " ") return <word pos="{position()}">{data($i)}</word>'
    PASSING 'Stack Overflow'  -- 替换为你的目标字符串
    COLUMNS 
      pos NUMBER PATH '@pos',
      word VARCHAR2(200) PATH '.'
  );

执行后直接得到期望结果:Sta•• Over••••

方案2:纯REGEXP_REPLACE实现(技巧性写法)

如果必须仅用REGEXP_REPLACE,可以结合分组匹配和动态长度计算,写法如下:

SELECT 
  LISTAGG(
    REGEXP_REPLACE(
      word,
      '^(\w{' || CEIL(LENGTH(word)/2) || '})(.*)$',
      '\1' || RPAD('', LENGTH(word) - CEIL(LENGTH(word)/2), '•')
    ),
    ' '
  ) WITHIN GROUP (ORDER BY pos) AS masked_text
FROM 
  XMLTABLE(
    'for $i in tokenize(., " ") return <word pos="{position()}">{data($i)}</word>'
    PASSING 'Stack Overflow'
    COLUMNS 
      pos NUMBER PATH '@pos',
      word VARCHAR2(200) PATH '.'
  );

原有SQL问题分析

你之前的代码:

SELECT REGEXP_REPLACE(REGEXP_REPLACE('Stack Overflow','(\w)\w','\1*'), '\*\w', '**') FROM DUAL;

逻辑是每两个字符保留第一个,替换第二个为*,再将后续的*+字符替换为**,最终导致每个单词仅保留首字符,完全不符合“保留前半部分”的规则,因此得到S•••• O•••••••的错误结果。

内容的提问来源于stack exchange,提问作者Anne.07

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:57:52