大写字符串中的单词

时间:2018-01-10 11:29:36

标签: sql oracle

我使用INITCAP来大写字符串中的单词,但我遇到了一个小问题:

select initcap(q'[JOE'S CARD 'N' CANDY]') from dual;

它会返回“ Joe'S Card'N'Candy ”,但我想知道是否还有其他方法可以将这些单词大写,因此它看起来像“ Joe's Card'N'Candy < / em>“(注意 s 是小写的)

2 个答案:

答案 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提供的唯一功能构建的复杂查询。

NB 此外,还有一个选项可以在Edgars T提供的link上创建等效的 java存储过程。有一个example

答案 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