我使用INITCAP来大写字符串中的单词,但我遇到了一个小问题:
select initcap(q'[JOE'S CARD 'N' CANDY]') from dual;
它会返回“ Joe'S Card'N'Candy ”,但我想知道是否还有其他方法可以将这些单词大写,因此它看起来像“ Joe's Card'N'Candy < / em>“(注意 s 是小写的)
答案 0 :(得分:3)
在我的位置,我会创建一个类似的自定义PL / SQL过程:
create or replace function initcap_cust(p_input varchar2)
return varchar2
as
l_input varchar2(4000) := lower(p_input);
l_capitalize_first_letter boolean := true;
l_output varchar2(4000) := null;
l_curr_char char(1);
begin
-- here we iterate over the lowercased string characters
for i in 1..length(l_input) loop
l_curr_char := substr(l_input, i, 1);
-- if we find a space - OK, next alphabet letter should be capitalized
-- you can add here more delimiters, e.g.: l_curr_char in (' ', ',', etc)
if l_curr_char = ' ' then
l_capitalize_first_letter := true;
end if;
-- makes O'Sullivan look this way
if regexp_like(l_output, '(^| )O''$') then
l_capitalize_first_letter := true;
end if;
-- found the first letter after delimiter - OK, capitalize
if l_capitalize_first_letter and (l_curr_char between 'a' and 'z') then
l_curr_char := upper(l_curr_char);
l_capitalize_first_letter := false;
end if;
-- build the output string
l_output := l_output || l_curr_char;
end loop;
return l_output;
end;
它适用于您的情况和类似情况。此外,它还可以根据您的需求进行自定义,而无需处理使用Oracle提供的唯一功能构建的复杂查询。
答案 1 :(得分:2)
改编自this answer以使用单个更简单的正则表达式来解析每个单词:
WITH names ( name ) AS (
SELECT 'FIRSTNAME O''MALLEY' FROM DUAL UNION
SELECT 'FIRST''NAME TEH''TE' FROM DUAL UNION
SELECT 'FORMAT ME BYGGER''N' FROM DUAL UNION
SELECT 'OLD MCDONALD' FROM DUAL UNION
SELECT 'EVEN OL''DER MACDONALD' FROM DUAL UNION
SELECT q'[JOE'S CARD 'N' CANDY]' FROM DUAL
)
SELECT name,
formatted_name
FROM names
MODEL
PARTITION BY (ROWNUM rn)
DIMENSION BY (0 dim)
MEASURES(name, CAST('' AS VARCHAR2(255)) word, CAST('' AS VARCHAR(255)) formatted_name)
RULES ITERATE(99) UNTIL (word[0] IS NULL)
(
word[0] = REGEXP_SUBSTR(name[0], '[^ ]+( *|$)', 1, ITERATION_NUMBER + 1),
formatted_name[0] = formatted_name[0]
-- Capitalise names starting with ', *', MC and MAC:
|| INITCAP(REGEXP_SUBSTR( word[0], '^([^'']?''|ma?c)?(.)(.*)$', 1, 1, 'i', 1 ) )
-- Capitalise the next letter of the word
|| UPPER( REGEXP_SUBSTR( word[0], '^([^'']?''|ma?c)?(.)(.*)$', 1, 1, 'i', 2 ) )
-- Lower case the rest of the word
|| LOWER( REGEXP_SUBSTR( word[0], '^([^'']?''|ma?c)?(.)(.*)$', 1, 1, 'i', 3 ) )
);
<强>输出强>:
NAME FORMATTED_NAME
----------------------- ----------------------
EVEN OL'DER MACDONALD Even Ol'der MacDonald
OLD MCDONALD Old McDonald
FIRST'NAME TEH'TE First'name Teh'te
FORMAT ME BYGGER'N Format Me Bygger'n
JOE'S CARD 'N' CANDY Joe's Card 'N' Candy
FIRSTNAME O'MALLEY Firstname O'Malley