title: Initcap with some restrictions
body: <p>I want to capitalize the every initial letter of a full name, but with a exception: the prepositions should be lowercase.</p>
  
  <p>The prepositions are: ["da", "de", "di", "do", "du", "das", "des", "dis", "dos", "dus"].</p>
  
  <p>I have this code so far, but it's horrible and incomplete. It will be so huge if I do this way (putting all the exceptions I need).</p>
  
  <pre><code>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'));
  </code></pre>
  
  <p>I already tried to use <code>REGEXP_REPLACE</code>(with this regex -> <code>^(d|D)[a-zA-Z]{1,2}$</code>) inside the <code>INITCAP</code> function, but I didn't get success.</p>
  
  <p>So, is there a way to do it easier?</p>
  
  <h2><strong>EDIT:</strong></h2>
  
  <p>I have this at the moment:</p>
  
  <pre><code>DBMS_OUTPUT.PUT_LINE(REGEXP_REPLACE(INITCAP('ronald DAS silva'), '([d|D][[:alpha:]]{1,2})', LOWER('\1')));
  </code></pre>
  
  <p>It's almost working, but the <code>LOWER</code> function for some reason is not doing his work, why? If I put LOWER('A') it works.</p>
  
  <h2><strong>Edit 2 - Additional tests:</strong></h2>
  
  <p>Every name that starts with the letter "d" will be transformed to lowercase, and it should not happen.</p>
  
  <p>Then there are some cases:</p>
  
  <ul>
  <li>Daniel</li>
  <li>Deivid</li>
  <li>Dijkstra</li>
  <li>Donald</li>
  <li>Duoling</li>
  </ul>
  
  <h2><strong>Full code</strong></h2>
  
  <pre><code>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;
  </code></pre>