Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>EDIT1 :</strong> Sorry, I forgot about the spaces management : here is <strong>a</strong> solution:</p> <pre><code>SET serveroutput ON format wraped; DECLARE l_text varchar2(64) := 'Tristram Vladimir Chan'; l_mask VARCHAR2(64) := '.....XXXX..XX.....X.XX'; l_res VARCHAR2(64); l_text_length INTEGER := length(l_text); l_mask_length INTEGER := length(l_mask); l_pos INTEGER := 1; l_p INTEGER := -1; l_x INTEGER := -1; l_b INTEGER := instr(l_text, ' '); l_lastb INTEGER := 0; l_cpt INTEGER := 1; BEGIN -- in case text length doesn't match mask length if l_mask_length &gt; l_text_length then l_mask := substr(l_mask, 1, l_text_length); elsif l_text_length &gt; l_mask_length then l_mask := rpad(l_mask, l_text_length, '.'); end if; l_mask_length := l_text_length; -- loop for each sequence of characters in the mask while l_pos &lt;= l_mask_length loop l_p := instr(l_mask, '.'); -- first '.' position l_x := instr(l_mask, 'X'); -- first 'X' position -- if "." or "X' has not been found if l_p = 0 or l_x = 0 then if l_p = 0 then -- no "." found, write 'X' until the end l_res := rpad(l_res, l_text_length, 'X'); elsif l_x = 0 then -- no "X" found, write text until the end l_res := l_res || substr(l_text, l_pos, l_text_length); end if; l_pos := l_mask_length+1; else if l_p = 1 then -- '.' found, write text until the next 'X' l_res := l_res || substr(l_text, l_pos, l_x-1); l_mask := substr(l_mask, l_x); l_pos := l_pos + l_x-1; elsif l_x = 1 then -- 'X' found, write 'X' until the next '.' l_res := rpad(nvl(l_res,'X'), nvl(length(l_res),0)+l_p-1, 'X'); l_mask := substr(l_mask, l_p); l_pos := l_pos + l_p-1; end if; end if; -- if a ' ' is found in the original text, replace it in the result if l_pos &gt; l_b and l_b &gt; l_lastb then l_b := instr(l_text, ' ', 1, l_cpt); l_res := substr(l_res, 1, l_b-1) || ' ' || substr(l_res,l_b+1,length(l_res)); l_lastb := l_b; l_cpt := l_cpt + 1; end if; end loop; dbms_output.put_line(l_res); END; </code></pre> <p>Result : <code>TristXXX VlXXimir XhXX</code></p> <p>It may be possible to improve it, I just wrote it "procedurally". The advantage compared to other solutions, is that here you can change the mask.</p> <p><strong>EDIT2</strong> : I reworked the code, it is pretty much simpler... :</p> <pre><code>SET serveroutput ON format wraped; DECLARE l_text varchar2(64) := 'Tristram Vladimir Chan'; l_mask VARCHAR2(64) := '.....XX..XX....XXXX...'; l_res VARCHAR2(64); l_text_length INTEGER := length(l_text); l_mask_length INTEGER := length(l_mask); l_pos INTEGER := 1; BEGIN -- in case text length doesn't match mask length if l_mask_length &gt; l_text_length then l_mask := substr(l_mask, 1, l_text_length); elsif l_text_length &gt; l_mask_length then l_mask := rpad(l_mask, l_text_length, '.'); end if; l_mask_length := l_text_length; -- loop and build the result string while l_pos &lt;= l_mask_length loop if substr(l_mask, l_pos, 1) = 'X' then l_res := l_res || 'X'; else l_res := l_res || substr(l_text, l_pos, 1); end if; if substr(l_text, l_pos, 1) = ' ' then l_res := substr(l_res, 1, l_pos-1) || ' '; end if; l_pos := l_pos + 1; end loop; dbms_output.put_line(l_res); END; </code></pre> <p>Result : <code>TristXXm XXadimXX Xhan</code></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload