0

我想将全名的每个首字母大写,但有一个例外:介词应该小写。

介词有:[“da”、“de”、“di”、“do”、“du”、“das”、“des”、“dis”、“dos”、“dus”]。

到目前为止我有这段代码,但它很糟糕而且不完整。如果我这样做(把我需要的所有例外),这将是巨大的。

DBMS_OUTPUT.PUT_LINE(
  REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE
    (INITCAP ('ronald DAS silva'), '(D|d)a', 'da'),
    '(D|d)o', 'do'), '(D|d)e', 'de'),'(D|d)o', 'do'),'(D|d)u', 'du'));

我已经尝试在函数内部使用REGEXP_REPLACE(使用此正则表达式 -> ^(d|D)[a-zA-Z]{1,2}$INITCAP,但没有成功。

那么,有没有办法让它更容易呢?

编辑:

我现在有这个:

DBMS_OUTPUT.PUT_LINE(REGEXP_REPLACE(INITCAP('ronald DAS silva'), '([d|D][[:alpha:]]{1,2})', LOWER('\1')));

它几乎可以工作,但是由于LOWER某种原因该功能没有做他的工作,为什么?如果我把 LOWER('A') 它工作。

编辑 2 - 附加测试:

每个以字母“d”开头的名称都将转换为小写,并且不应该发生这种情况。

然后有一些情况:

  • 丹尼尔
  • 神威
  • 迪杰斯特拉
  • 唐纳德
  • 多苓

完整代码

DECLARE
  TYPE t_name IS VARRAY(3) OF VARCHAR2(100);
  v_names t_name := t_name('    Donald     dIs    siLvA',
                           'daniEl    da sIlvA XaVIeR   ',
                           '   DeYse De Olivier dA     loPeS');
BEGIN
  DBMS_OUTPUT.PUT_LINE(RPAD('Name w/o format', 60, ' ') ||
                            'Name formatted');
  DBMS_OUTPUT.PUT_LINE(RPAD('---------------------', 60, ' ') ||
                            '---------------------');

  FOR i IN 1..v_names.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(RPAD(v_names(i), 60, ' ') ||
                          f_format(v_names(i)));
  END LOOP;
END;

FUNCTION f_format(p_str VARCHAR2)
   RETURN VARCHAR2
AS
BEGIN
RETURN REGEXP_REPLACE(
         REGEXP_REPLACE(
           INITCAP(p_str),
         '((D)([aeiou](s|$)?))', 'd\3'),
       '[[:space:]]+', ' ');       
END;
4

1 回答 1

0

我想我明白了。初始化整个字符串,然后查找被空格包围的模式(记住第 1 组)。在其中,将其分开,因此第 2 组是前导大写字母“D”,第 3 组是其余部分,包括可选的“s”。替换为空格、小写“d”、记住的第 3 组和另一个空格。不过,我不得不建议不要在生产中使用它,因为它对于这种名称格式来说太具体了。

SQL> declare
     name varchar2(20) := 'ronald dis silva';
   begin
     dbms_output.put_line(
       REGEXP_REPLACE(INITCAP(name), '( (D)([aeiou](s|$)?) )', ' d\3 '));
   end;
   /
Ronald dis Silva

SQL>

以“d”开头的名字对我有用:

SQL> declare
  2       name varchar2(20) := 'donald dis silva';
  3     begin
  4       dbms_output.put_line(
  5         REGEXP_REPLACE(INITCAP(name), '( (D)([aeiou](s|$)?) )', ' d\3 '));
  6     end;
  7  /
Donald dis Silva

使用 WITH 子句以更容易插入不同名称进行测试的一些更复杂名称的示例:

SQL> with tbl(name) as (
      select '    Donald     dIs    siLvA'      from dual union
      select 'daniEl    da sIlvA XaVIeR   '     from dual union
      select '   DeYse De Olivier dA     loPeS' from dual
    )
    select REGEXP_REPLACE(INITCAP(REGEXP_REPLACE(trim(name), '\s+', ' ')), '( (D)([aeiou](s|$)?) )', ' d\3 ') newname
    from tbl;

NEWNAME
--------------------------------------------------------------------------------
Donald dis Silva
Deyse de Olivier da Lopes
Daniel da Silva Xavier

SQL>
于 2016-03-25T15:42:02.293 回答