oracle专栏中的SSN正则表达式

时间:2018-04-24 10:38:05

标签: regex oracle

我试图在我的oracle查询中屏蔽SSN细节。

使用以下查询识别SSN格式并将其替换为给定格式。

  1. DDDDDDDDD
  2. DDD-DD-DDDD
  3.   

    选择regexp_replace(' 123-45-6789',   (?^ | \ d +);&#39 |(?$ | \ d +)(\ d {3} - - \ d {2} \ d {5})(\ d {4})&#39 ;, ' \ 1 ***** \ 3 \ 4')ouptut   来自双重

    如果我运行此查询,我会得到以下输出。

      

    ***** 6789

    同样,我也想解析下面的格式。

      

    DD-DDDDDDD

    如果连字符可以在任何地方,可能会更好,但它应该只读取9位数。

    由于我对RegEx不太熟悉,有人可以帮我构建这个要求的正则表达式吗?

4 个答案:

答案 0 :(得分:2)

如果你想在忽略破折号时解析SSN,最好的方法可能是在尝试应用正则表达式之前替换任何破折号(假设这些是你需要担心的唯一非数字):

REPLACE(myssn, '-', '')

然后您可以应用正则表达式(尽管可能有更有效的方法来执行此操作; Oracle中的正则表达式非常昂贵):

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

就我个人而言,我可能会尝试以下内容,并完全避免使用正则表达式:

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

希望这有帮助。

答案 1 :(得分:2)

如果您想利用Oracle数据库提供的现有功能,这是一个机会。

Oracle Redaction功能允许在数据库中设置编校策略,这样当没有特权的用户查询数据时,他们只能看到他们应该能够做什么,这可能是什么,随机数据或部分编辑数据。

其中一项功能包括一些针对社会安全号码的内置政策。

如果您当前的安装可以使用此功能,请查看它,因为它可以为您的应用程序和报告层节省大量工作。

以下是SS#的内置政策:

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

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

答案 2 :(得分:1)

这将捕获组中的前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

答案 3 :(得分:0)

在正则表达式/新要求的行之间进行阅读,您可以看到:

  • 字符串开头的零个或多个非数字字符
  • 符合格式的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