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

使用INITCAP大写字符串单词遇问题,求实现撇号后字符小写的方法

解决Oracle INITCAP撇号后字母大写的问题

我懂你的困扰——INITCAP确实会把撇号这类非字母字符后的第一个字母转成大写,导致JOE'S变成Joe'S而不是你想要的Joe's。这是因为Oracle默认把所有非字母字符都当作单词分隔符,所以撇号后面的s会被当作新单词的首字母大写。

下面给你两种可行的解决办法:

方法1:用正则表达式快速修正

可以先通过INITCAP处理大部分内容,再用REGEXP_REPLACE把撇号后的大写字母转成小写:

SELECT REGEXP_REPLACE(
    INITCAP(q'[JOE'S CARD 'N' CANDY]'),
    '(''[A-Z])',
    '\L\1',
    1,
    0,
    'c'
) FROM DUAL;

解释:

  • ''[A-Z]:匹配撇号后跟一个大写字母的模式
  • \L\1:把匹配到的部分(撇号+大写字母)中的字母转成小写
  • 最后一个参数'c'表示区分大小写,确保只替换大写字母

执行这个语句会得到你想要的结果:Joe's Card 'N' Candy

方法2:自定义INITCAP函数(更灵活)

如果你的场景需要频繁处理这类字符串,写一个自定义函数会更方便,能完全按照你的规则控制大小写:

CREATE OR REPLACE FUNCTION CUSTOM_INITCAP(p_input_str IN VARCHAR2) RETURN VARCHAR2 IS
    v_output_str VARCHAR2(4000) := '';
    v_prev_char CHAR(1);
    v_current_char CHAR(1);
    v_need_capitalize BOOLEAN := TRUE;
BEGIN
    FOR i IN 1..LENGTH(p_input_str) LOOP
        v_current_char := SUBSTR(p_input_str, i, 1);
        
        IF v_need_capitalize THEN
            v_output_str := v_output_str || UPPER(v_current_char);
            v_need_capitalize := FALSE;
        ELSE
            -- 若前一个字符是撇号,当前字母转小写
            IF v_prev_char = '''' AND v_current_char BETWEEN 'A' AND 'Z' THEN
                v_output_str := v_output_str || LOWER(v_current_char);
            ELSE
                v_output_str := v_output_str || LOWER(v_current_char);
            END IF;
        END IF;
        
        -- 只有遇到非字母字符时,才标记下一个字母需要大写
        IF NOT (v_current_char BETWEEN 'A' AND 'Z' OR v_current_char BETWEEN 'a' AND 'z') THEN
            v_need_capitalize := TRUE;
        END IF;
        
        v_prev_char := v_current_char;
    END LOOP;
    
    RETURN v_output_str;
END;
/

调用这个函数:

SELECT CUSTOM_INITCAP(q'[JOE'S CARD 'N' CANDY]') FROM DUAL;

这个函数会保留撇号后的字母为小写,同时正常处理其他单词的首字母大写,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:50:28