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 に答える