Java 正则表达式匹配并用相同长度的字符替换匹配的组
Java Regex Match and Replace matched group with characters of same length
所以我想匹配信用卡号并以 6*4 格式屏蔽它们。这样只有前 6 个和后 4 个字符可见。之间的字符将是“*”。我试着用像这样的面具来解决这个问题;
private static final String MASK = "***";
matcher.replaceAll(MASK);
但找不到方法让我在中间返回与 $2 组等长的星星。
然后我实现了下面的代码并且它起作用了。
但我想问的是,是否有更短或更简单的方法来做到这一点。有人知道吗?
private static final String HIDING_MASK = "**********";
private static final String REGEX = "\b([0-9]{6})([0-9]{3,9})([0-9]{4})\b";
private static final int groupToReplace = 2;
private String formatMessage(String message) throws NotMatchedException {
Matcher m = Pattern.compile(REGEX).matcher(message);
if (!m.find()) throw new NotMatchedException();
else {
StringBuilder maskedMessage = new StringBuilder(message);
do {
maskedMessage.replace(m.start(groupToReplace), m.end(groupToReplace),
HIDING_MASK.substring(0, (m.end(groupToReplace) - m.start(groupToReplace))));
} while(m.find(m.end()));
return maskedMessage.toString();
}
}
编辑: 这是要处理的 示例 消息。
"2017.08.26 20:51 [Thread-Name] [Class-Name] [MethodName] 信用卡持有人12345678901234567 02/2022 123 ......"
private String formatMessage(String message) throws NotMatchedException {
if (message.matches(".*\b\d{13,19}\b.*")) {
return message.replaceAll("(?:[.\b]*)(?<=\d{6})\d(?=\d{4})(?:[.\b]*)", "*");
} else {
throw new NotMatchedException() ;
}
}
您可以使用以下代码轻松完成:
str.replaceAll( "(?<=\d{6})\d(?=\d{4})", "*" );
16 个字符的简单解决方案"number":
String masked = num.substring(0,6) + "******" + num.substring(12,16);
对于任意长度的字符串 ( >10 ):
String masked = num.substring(0,6)
+ stars(num.length() - 10)
+ num.substring(num.length() - 6);
... 其中 stars(int n)
returns String
颗 n
颗星。请参阅 Simple way to repeat a String in java——或者如果您不介意 9 颗星的限制,"*********".substring(0,n)
可读但不酷。
String in = "1234561231234";
String mask = in
.replaceFirst("^\d{6}(\d+)\d{4}$", "")
.replaceAll("\d", "\*");
String out = in
.replaceFirst("^(\d{6})\d+(\d{4})$", "" + mask + "");
使用 StringBuffer
并覆盖所需的字符:
StringBuffer buf = new StringBuffer(num);
for(int i=4; i< buf.length() - 6) {
buf.setCharAt(i, '*');
}
return buf.toString();
您也可以使用 buf.replace(int start, int end, String str)
如果您的文本包含多个长度可变的信用卡号,您可以使用以下方法:
str.replaceAll( "\b(\d{13,19})\b", "\u0000\u0000" )
.replaceAll( "(?<=\d{6})(?<=\u0000\d{6,14})\d(?=\d{4,12}\u0000)(?=\d{4})", "*" )
.replaceAll( "\u0000([\d*]+)\u0000", "" );
虽然不是很可读,但是一气呵成。
所以我想匹配信用卡号并以 6*4 格式屏蔽它们。这样只有前 6 个和后 4 个字符可见。之间的字符将是“*”。我试着用像这样的面具来解决这个问题;
private static final String MASK = "***";
matcher.replaceAll(MASK);
但找不到方法让我在中间返回与 $2 组等长的星星。
然后我实现了下面的代码并且它起作用了。 但我想问的是,是否有更短或更简单的方法来做到这一点。有人知道吗?
private static final String HIDING_MASK = "**********";
private static final String REGEX = "\b([0-9]{6})([0-9]{3,9})([0-9]{4})\b";
private static final int groupToReplace = 2;
private String formatMessage(String message) throws NotMatchedException {
Matcher m = Pattern.compile(REGEX).matcher(message);
if (!m.find()) throw new NotMatchedException();
else {
StringBuilder maskedMessage = new StringBuilder(message);
do {
maskedMessage.replace(m.start(groupToReplace), m.end(groupToReplace),
HIDING_MASK.substring(0, (m.end(groupToReplace) - m.start(groupToReplace))));
} while(m.find(m.end()));
return maskedMessage.toString();
}
}
编辑: 这是要处理的 示例 消息。 "2017.08.26 20:51 [Thread-Name] [Class-Name] [MethodName] 信用卡持有人12345678901234567 02/2022 123 ......"
private String formatMessage(String message) throws NotMatchedException {
if (message.matches(".*\b\d{13,19}\b.*")) {
return message.replaceAll("(?:[.\b]*)(?<=\d{6})\d(?=\d{4})(?:[.\b]*)", "*");
} else {
throw new NotMatchedException() ;
}
}
您可以使用以下代码轻松完成:
str.replaceAll( "(?<=\d{6})\d(?=\d{4})", "*" );
16 个字符的简单解决方案"number":
String masked = num.substring(0,6) + "******" + num.substring(12,16);
对于任意长度的字符串 ( >10 ):
String masked = num.substring(0,6)
+ stars(num.length() - 10)
+ num.substring(num.length() - 6);
... 其中 stars(int n)
returns String
颗 n
颗星。请参阅 Simple way to repeat a String in java——或者如果您不介意 9 颗星的限制,"*********".substring(0,n)
可读但不酷。
String in = "1234561231234";
String mask = in
.replaceFirst("^\d{6}(\d+)\d{4}$", "")
.replaceAll("\d", "\*");
String out = in
.replaceFirst("^(\d{6})\d+(\d{4})$", "" + mask + "");
使用 StringBuffer
并覆盖所需的字符:
StringBuffer buf = new StringBuffer(num);
for(int i=4; i< buf.length() - 6) {
buf.setCharAt(i, '*');
}
return buf.toString();
您也可以使用 buf.replace(int start, int end, String str)
如果您的文本包含多个长度可变的信用卡号,您可以使用以下方法:
str.replaceAll( "\b(\d{13,19})\b", "\u0000\u0000" )
.replaceAll( "(?<=\d{6})(?<=\u0000\d{6,14})\d(?=\d{4,12}\u0000)(?=\d{4})", "*" )
.replaceAll( "\u0000([\d*]+)\u0000", "" );
虽然不是很可读,但是一气呵成。