Regex для SSN в колонке оракула
Я пытаюсь замаскировать детали SSN в моем запросе оракула.
Использовал приведенный ниже запрос для определения форматов SSN и замены его на заданный формат.
- DDDDDDDDD
- ддд-дд-дддд
выберите 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