Regex для SSN в колонке оракула

Я пытаюсь замаскировать детали SSN в моем запросе оракула.

Использовал приведенный ниже запрос для определения форматов SSN и замены его на заданный формат.

  1. DDDDDDDDD
  2. ддд-дд-дддд

выберите regexp_replace('123-45-6789', '(^|\D+?)(\d{3}-\d{2}-|\d{5})(\d{4})($|\D+?)', '\1*****\3\4') выход из двойного

Если я запускаю этот запрос, я получаю вывод ниже.

***** 6789

Точно так же я хочу разобрать формат ниже.

дд-DDDDDDD

Или может быть лучше, если где-нибудь дефис может быть, но он должен просто прочитать 9 цифр.

Поскольку я не очень хорошо знаком с RegEx, может ли кто-нибудь помочь мне построить регулярное выражение для этого требования?

4 ответа

Решение

Это захватит первые 5 чисел в группе и полностью игнорирует любые тире

-*(\d-*){5}((\d-*){4})

Примеры

  • В: select regexp_replace('123-45-6789', '-*(\d-*){5}((\d-*){4})', '*****\2')

    • Из: *****6789
  • В: select regexp_replace('12-3456789', '-*(\d-*){5}((\d-*){4})', '*****\2')

    • Из: *****6789
  • В: select regexp_replace('---12-3--4567-89', '-*(\d-*){5}((\d-*){4})', '*****\2')

    • Из: *****67-89

Если вы хотите анализировать номера SSN, игнорируя тире, лучшим способом может быть замена любых тире (при условии, что это единственные нечисловые значения, о которых вам нужно беспокоиться) перед попыткой применения регулярного выражения:

REPLACE(myssn, '-', '')

Затем вы можете применить регулярное выражение (хотя может быть более эффективный способ сделать это; регулярные выражения в Oracle довольно дороги):

SELECT REGEXP_REPLACE( REPLACE(myssn, '-', ''), '^.*\(d{4})$', '*****\1' )
  FROM mytable;

Лично я мог бы попробовать что-то вроде следующего, и полностью избежать регулярного выражения:

SELECT '*****' || SUBSTR( REPLACE(myssn, '-', ''), -4, 4 )
  FROM mytable;

Надеюсь это поможет.

Если вы хотите воспользоваться преимуществами существующих функций, предоставляемых базой данных Oracle, у вас есть такая возможность.

Функция Oracle Redaction позволяет устанавливать политики редактирования в базе данных, так что когда непривилегированные пользователи запрашивают данные, они видят только то, что им нужно, что может быть ничем, случайными данными или частично отредактированными данными.

Одной из включенных функций являются некоторые встроенные политики для номеров социального страхования.

Если эта функция доступна для вашей текущей установки, проверьте ее, так как она может сэкономить вам массу работы на уровне приложений и отчетов.

Вот встроенные политики для SS#:

https://docs.oracle.com/cloud/latest/db121/ASOAG/redaction_config.htm

Example 5-7 Partially Redacted Character Values

BEGIN
 DBMS_REDACT.ADD_POLICY(
   object_schema       => 'mavis', 
   object_name         => 'cust_info', 
   column_name         => 'ssn',
   policy_name         => 'redact_cust_ssns3', 
   function_type       => DBMS_REDACT.PARTIAL,
   function_parameters => DBMS_REDACT.REDACT_US_SSN_F5,
   expression          => '1=1',
   policy_description  => 'Partially redacts 1st 5 digits in SS numbers',
   column_description  => 'ssn contains Social Security numbers');
END;
/
Query and redacted result:

SELECT ssn FROM mavis.cust_info;

SSN
-------
XXX-XX-4320
XXX-XX-4323
XXX-XX-4325
XXX-XX-4329

Читая между строк вашего регулярного выражения / нового требования, вы можете получить:

  • Ноль или более нецифровых символов в начале строки
  • SSN, соответствующий форматам:
    • ddddddddd
    • ddd-dd-dddd или же
    • dd-ddddddd
  • Ноль или более нецифровых символов в конце строки

Вы можете использовать регулярные выражения:

  • ^\D*\d{2}(\d{3})(\d{4})\D*$
  • ^\D*\d{2}(\d-\d\d-)(\d{4})\D*$
  • ^\D*\d{2}(-\d{3})(\d{4})\D*$

Соответственно, чтобы сопоставить эти 3 шаблона и (поскольку единственное отличие - 1-я группа захвата), вы можете объединить их в одно выражение:

^\D*\d{2}(-?\d{3}|\d-\d\d-)(\d{4})\D*$

Итак, ваш запрос будет:

SELECT REGEXP_REPLACE(
         'TEST12-3456789TEST',
         '*****\2'
       )
FROM   DUAL
Другие вопросы по тегам