我正在尝试使用正则表达式打印字符串的第二个字符和最后四个字符。
这是我的正则表达式,它只打印字符串的+和最后四个:
s.replaceAll("\w(?=\w{4})", "*");
我使用:"+133445678"作为测试假人数据。
我希望它是:+1******5678我得到:+*******5678
我做错了什么?
使用单个regexp屏蔽电话号码可能很复杂。一段时间后,可能需要一段时间才能回忆起regexp(?<!^+)[0-9](?=[0-9]{4})
的作用😊
更直接的解决方案是使用substring
方法和简单的替换replaceAll("\d", "*")
:
private static String maskPhoneNumber(String tel) {
if (tel.length() < 6) {
return tel;
}
return tel.substring(0, 2)
+ tel.substring(2, tel.length() - 4).replaceAll("\d", "*")
+ tel.substring(tel.length() - 4);
}
示例
maskPhoneNumber("+13334445678"); // +1******5678
maskPhoneNumber("+1-333-444-5678"); // +1-***-***-5678
maskPhoneNumber("+1 (333) 444-5678"); // +1 (***) ***-5678
如果您不想保留电话号码格式(短划线、空格、括号(,请使用添加一个替换项(replaceAll("[^\d]", "")
(:
tel.substring(0, 2)
+ tel.substring(2, tel.length() - 4)
.replaceAll("[^\d]", "")
.replaceAll("\d", "*")
+ tel.substring(tel.length() - 4);
示例
maskPhoneNumber("+13334445678"); // +1******5678
maskPhoneNumber("+1-333-444-5678"); // +1******5678
maskPhoneNumber("+1 (333) 444-5678"); // +1******5678
这样的命令式代码不像一个regexp那么优雅,但可能更容易被任何开发人员理解。
如果要匹配最后4位数字,可以使用(.{4})\s*$
。此正则表达式将返回输入字符串的最后4个字符,而不考虑末尾的空格。
您的模式w(?=w{4})
也将匹配加号后的数字1,因为它匹配一个单词字符,并断言右边应该是4个单词字符。
一种选择是添加一个负的后备(?<!^+)
,以断言左边的不是后面跟着加号的字符串^
的开头
您可以匹配数字[0-9]
,而不是匹配单词字符。
(?<!^+)[0-9](?=[0-9]{4})
Regex演示| Java演示
例如
String s = "+13334445678";
System.out.println(s.replaceAll("(?<!^\+)[0-9](?=[0-9]{4})", "*"));
输出
+1******5678
如果is不在字符串的开头,另一个选项可能是断言左边的不是加号,在前面没有非空白字符:
(?<!(?<!S)+)[0-9](?=[0-9]{4})
Regex演示
如果您想在格式中保留任何短划线,这里有一个替代方法,使用lambda替换方法:
public static void main(String[] args) {
Pattern phoneObfuscator = Pattern.compile("(?<=\+\d)[\d-]+(?=\d{4})");
Pattern digit = Pattern.compile("\d");
List<String> numbers = List.of("+13334445678", "+1-123-456-7890");
for (String number : numbers) {
String result = phoneObfuscator.matcher(number).replaceAll(
m -> digit.matcher(m.group()).replaceAll("*"));
System.out.printf("%s -> %s%n", number, result);
}
}
它匹配+N和NNNN之间的整个字符串,并用*
替换每个数字。
如果多次运行regex,通常最好使用编译后的版本。
您可以使用捕获组来执行此任务。正则表达式将匹配整个电话号码,包括国家代码。由于您希望掩码值具有国家代码和最后四位数字,因此您可以使用捕获组来捕获它们。然后,您可以将它们包括在替换中。下面的链接详细解释了正则表达式的每个部分的作用。
https://regexr.com/4rcq7
String text = "+13334445678 +11234567890";
String regex = "(\+1)\d{6}(\d{4})";
String replacement = "$1******$2";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
System.out.println(matcher.replaceAll(replacement));