【问题标题】:Mask all SSN with only partial Mask from a file with multiple SSNs从具有多个 SSN 的文件中仅使用部分掩码屏蔽所有 SSN
【发布时间】:2019-08-31 01:14:31
【问题描述】:

首先声明我对正则表达式很糟糕。我想在字符串中查找社会安全号码的每个实例,并屏蔽除破折号 (-) 和 SSN 的最后 4 个以外的所有内容。

示例

String someStrWithSSN = "This is an SSN,123-31-4321, and here is another 987-65-8765";
Pattern formattedPattern = Pattern.compile("^\\d{9}|^\\d{3}-\\d{2}-\\d{4}$");
Matcher formattedMatcher = formattedPattern.matcher(someStrWithSSN);

while (formattedMatcher.find()) {
    // Here is my first issue.  not finding the pattern
}

// my next issue is that I need to my String should look like this
//     "This is an SSN,XXX-XX-4321, and here is another XXX-XX-8765"

预期结果是找到每个 SSN 并替换。上面的代码应该产生字符串,“”这是一个 SSN,XXX-XX-4321,这里是另一个 XXX-XX-8765”

【问题讨论】:

    标签: java regex


    【解决方案1】:

    您可以通过执行以下操作来简化此操作:

    String initial = "This is an SSN,123-31-4321, and here is another 987-65-8765";
    String processed = initial.replaceAll("\\d{3}\\-\\d{2}(?=\\-\\d{4})","XXX-XX");
    System.out.println(initial);
    System.out.println(processed);
    

    输出:

    这是一个 SSN,123-31-4321,这是另一个 987-65-8765
    这是一个SSN,XXX-XX-4321,这里是另一个XXX-XX-8765

    正则表达式 \d{3}\-\d{2}(?=\-\d{4}) 捕获三位数字,后跟两位数字,用破折号分隔(然后是破折号和 4 位数字,非捕获)。然后将replaceAll 与此正则表达式一起使用将创建所需的掩蔽效果。

    编辑:

    如果您还希望此替换针对 9 个连续数字,您可以执行以下操作:

    String initial = "This is an SSN,123-31-4321, and here is another 987658765";
    String processed = initial.replaceAll("\\d{3}\\-\\d{2}(?=\\-\\d{4})","XXX-XX")
                           .replaceAll("\\d{5}(?=\\d{4})","XXXXX");
    System.out.println(initial);
    System.out.println(processed);
    

    输出:

    这是一个 SSN,123-31-4321,这是另一个 987658765
    这是一个SSN,XXX-XX-4321,这里是另一个XXXXX8765

    正则表达式\d{5}(?=\d{4}) 捕获五位数字(后跟四位数字,非捕获)。使用第二次调用 replaceAll 将针对这些序列进行适当的替换。

    编辑: 这是之前正则表达式的更强大版本,以及新正则表达式如何工作的更长演示:

    String initial = "123-45-6789 is a SSN that starts at the beginning of the string,
        and still matches. This is an SSN, 123-31-4321, and here is another 987658765. These
        have 10+ digits, so they don't match: 123-31-43214, and 98765876545.
        This (123-31-4321-blah) has 9 digits, but is followed by a dash, so it doesn't match.
        -123-31-4321 is preceded by a dash, so it doesn't match as well. :123-31-4321 is 
        preceded by a non-colon/digit, so it does match. Here's a 4-2-4 non-SSN that would've
        tricked the initial regex: 1234-56-7890. Here's two SSNs in parentheses: (777777777) 
        (777-77-7777), and here's four invalid SSNs in parentheses: (7777777778) (777-77-77778)
        (777-778-7777) (7778-77-7777). At the end of the string is a matching SSN:
        998-76-4321";
    String processed = initial.replaceAll("(?<=^|[^-\\d])\\d{3}\\-\\d{2}(?=\\-\\d{4}([^-\\d]|$))","XXX-XX")
                           .replaceAll("(?<=^|[^-\\d])\\d{5}(?=\\d{4}($|\\D))","XXXXX");
    System.out.println(initial);
    System.out.println(processed);
    

    输出:

    123-45-6789 是从字符串开头开始的 SSN,并且仍然匹配。这是一个 SSN,123-31-4321,这是另一个 987658765。这些有 10 多个数字,所以它们不匹配:123-31-43214 和 98765876545。这个 (123-31-4321-blah) 有9 位数字,但后跟一个破折号,因此不匹配。 -123-31-4321 前面有一个破折号,所以它也不匹配。 :123-31-4321 前面有一个非冒号/数字,所以它匹配。这是一个可以欺骗初始正则表达式的 4-2-4 非 SSN:1234-56-7890。这是括号中的两个 SSN:(777777777) (777-77-7777),括号中是四个无效的 SSN:(7777777778)(777-77-77778) (777-778-7777) (7778-77-7777)。字符串末尾是匹配的 SSN:998-76-4321

    XXX-XX-6789 是一个 SSN,它从字符串的开头开始,并且仍然匹配。这是一个 SSN,XXX-XX-4321,这是另一个 XXXXX8765。这些有 10 位以上的数字,所以它们不匹配:123-31-43214 和 98765876545。这个 (123-31-4321-blah) 有 9 位数字,但后面是一个破折号,所以它不匹配。 -123-31-4321 前面有一个破折号,所以它也不匹配。 :XXX-XX-4321 前面有一个非冒号/数字,所以它确实匹配。这是一个可以欺骗初始正则表达式的 4-2-4 非 SSN:1234-56-7890。括号中是两个 SSN:(XXXXX7777) (XXX-XX-7777),括号中是四个无效 SSN:(7777777778)(777-77-77778) (777-778-7777) (7778-77-7777)。字符串末尾是匹配的 SSN:XXX-XX-4321

    【讨论】:

    • 所以我对第二个正则表达式 ("\\d{5}(?=\\d{4})","XXXXX") 确实有问题。我希望它只匹配 9 位数字。如果有 10 位以上的数字,它会屏蔽。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 2019-06-02
    相关资源
    最近更新 更多