正则表达式将所有匹配替换为具有相同长度的符号

时间:2017-01-11 04:00:18

标签: java regex

我的应用程序当前记录了我需要屏蔽的敏感信息。

当前日志行如下所示:

<Unable to fetch user info combination of dob=[20001231] and pan=[ABCD1234Z]

但应改为

<Unable to fetch user info combination of dob=******** and pan=********>

我试图用

来掩饰这个
str.replaceAll("\\[.*?\\]", "*")

但它改为:

<Unable to fetch user info combination of dob=* and pan=*>

如何在方括号之间屏蔽字符时保留字符数量?

3 个答案:

答案 0 :(得分:3)

可以在一行中完成:

str = str.replaceAll("(?=[^\\[]+]).", "*");

请参阅live regex demo和/或live Java demo

这保留了方括号。要从结果中省略它们,请使用:

str = str.replaceAll("\\[?(?=[^\\[]*]).]?", "*");

请参阅live Java demo

答案 1 :(得分:2)

您可以操作Pattern和Matcher来执行此操作。例如:

String log = "<Unable to fetch user info combination of dob=[20001231] and pan=[ABCD1234Z]>";
Pattern pattern = Pattern.compile("\\[.*?\\]");
Matcher  matcher = pattern.matcher(log);
String match="";
while (matcher.find()){
    match=matcher.group();
    char[] symbols = new char[match.length()];
    Arrays.fill(symbols, '*');
    log = log.replace(match, new String(symbols));  
}
System.out.println(log);   

输出:

<Unable to fetch user info combination of dob=******** and pan=********>

上面的例子中可能存在一些性能问题,但至少你有这个想法。

答案 2 :(得分:0)

在这里查看类似的问题,例如:Customising log4j logging for sensitive data。它建议覆盖toString()。你可以在这里做同样的事情。当然,如果你泛是String,那么它可能会更难。您可以将其包装到Pan类并在此处创建toString:

@Data
@NoArgsConstructor
class Pan {
    private String value;

    @Override
    public String toString() {
        return Optional.ofNullable(value).map(x -> "***").orElse(null);
    }
}

它将阻止在所有日志消息中随处写入Pan,而不仅仅是在您的特定日志消息中。

使用toString:

Pan pan = new Pan();
pan.setValue("123456789");
log.error("<Unable to fetch user info combination of dob=[{}] and pan=[{}]>", dob, pan);