Oracle: заменить все символы звездочкой, кроме первых 3 букв каждого слова - PullRequest
0 голосов
/ 01 октября 2019

В ORACLE я хотел бы заменить все символы каждого слова звездочкой, кроме 3 первых букв.

Пример

До:

Company Microsoft Technology

После:

Com**** Mic****** Tec*******

Я думаю, что могу использовать функцию REGEXP_REPLACE. Большое спасибо

Ответы [ 2 ]

3 голосов
/ 01 октября 2019

Для каждой подстроки без пробелов в каждом предложении, а затем объединить предыдущую часть предложения с первой подстрокой длиной до 3 символов, а затем заменить оставшуюся часть слова на * (вы можетеиспользуйте LPAD( '*', length, '*' ) для этого`, а затем восстановите предложение и выполните это итеративно, что можно сделать в условии факторизации рекурсивного подзапроса:

Тестовые данные :

CREATE TABLE test_data ( value ) AS
 SELECT 'Company Microsoft Technology' FROM DUAL UNION ALL
 SELECT ' a bb ccc dddd eeeee' FROM DUAL UNION ALL
 SELECT 'Smith-Smythe O''Brien' FROM DUAL

Запрос :

WITH bounds ( value, start_pos, end_pos ) AS (
  SELECT value,
         1,
         1
  FROM   test_data
UNION ALL
  SELECT SUBSTR( value, 1, start_pos - 1 )
         || SUBSTR( value, start_pos, LEAST( end_pos - start_pos, 3 ) )
         || LPAD( '*', GREATEST( 0, end_pos - start_pos - 3 ), '*' )
         || SUBSTR( value, end_pos ),
         REGEXP_INSTR( value, '\S+', end_pos, 1, 0 ),
         REGEXP_INSTR( value, '\S+', end_pos, 1, 1 )
  FROM   bounds
  WHERE  end_pos > 0
)
SELECT value
FROM   bounds
WHERE  end_pos = 0;

Вывод :

| VALUE                        |
| :--------------------------- |
| Smi********* O'B****         |
| Com**** Mic****** Tec******* |
|  a bb ccc ddd* eee**         |

дБ<> скрипка здесь

1 голос
/ 01 октября 2019

Еще один подход (спасибо, MT0, за тестовый пример и комментарии, которые вы уже разместили).

SQL> with test (col) as
  2    (SELECT 'Company Microsoft Technology' FROM DUAL UNION ALL
  3     SELECT ' a bb ccc dddd eeeee'         FROM DUAL UNION ALL
  4     SELECT 'Smith-Smythe O''Brien'        FROM DUAL
  5    ),
  6  tsplit as
  7    (select regexp_substr(col, '[^ ]+', 1, column_value) val,
  8            column_value rn,
  9            col
 10     from test cross join table(cast(multiset(select level from dual
 11                                              connect by level <= regexp_count(col, ' ') + 1
 12                                             ) as sys.odcinumberlist))
 13    )
 14  select
 15    listagg(case when length(val) > 3 then substr(val, 1, 3) || lpad('*', length(val) - 3, '*')
 16                 else val
 17            end, ' ') within group (order by rn) result
 18  from tsplit
 19  group by col;

RESULT
--------------------------------------------------------------------------------
a bb ccc ddd* eee**
Com**** Mic****** Tec*******
Smi********* O'B****

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...