使用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
相关产品推荐
相关产品推荐

