Reputation:
I am trying to use regular expression to print the second character and the last four characters of a string.
This is the regular expression I have and its only printing the + and the last four of the string:
s.replaceAll("\\w(?=\\w{4})", "*");
I am using: "+13334445678 " as test dummie data.
I am wanting it to be: +1******5678 I am getting: +*******5678
What am I doing wrong?
Upvotes: 3
Views: 2376
Reputation: 3
You can use capture groups to perform this task. The regex would match the entire phone number, including the country code. Since you want the masked value to have the country code and last four digits, you'd use capture groups to capture them. Then, you can include them in the replacement. The below link explains in detail what each part of the regex does.
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));
Upvotes: 0
Reputation: 10315
Masking phone number using single regexp may be complicated.
After some time, it may take a while to recall what regexp (?<!^\+)[0-9](?=[0-9]{4})
does 😊
More straightforward solution is to use substring
method and simple replacement 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);
}
Examples
maskPhoneNumber("+13334445678"); // +1******5678
maskPhoneNumber("+1-333-444-5678"); // +1-***-***-5678
maskPhoneNumber("+1 (333) 444-5678"); // +1 (***) ***-5678
If you don't want to preserve a phone number format (dashes, spaces, brackets), use add one more replacement (replaceAll("[^\\d]", "")
):
tel.substring(0, 2)
+ tel.substring(2, tel.length() - 4)
.replaceAll("[^\\d]", "")
.replaceAll("\\d", "*")
+ tel.substring(tel.length() - 4);
Examples
maskPhoneNumber("+13334445678"); // +1******5678
maskPhoneNumber("+1-333-444-5678"); // +1******5678
maskPhoneNumber("+1 (333) 444-5678"); // +1******5678
Such imperative style code is not so elegant as a single regexp but potentially is easier to understand by any developer.
Upvotes: 3
Reputation: 761
In case you wanted to preserve any dashes in the format, here is an alternative, using the lambda replace method:
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);
}
}
It matches the whole string between the +N and NNNN and replaces each digit with *
.
If running a regex multiple times it is usually better to use the compiled version.
Upvotes: 0
Reputation: 163362
Your pattern \w(?=\w{4})
will also match the digit 1 after the plus sign because it matches a word character and asserts that what is on the right should be 4 word characters.
One option is to add a negative lookbehind (?<!^\+)
to assert what is on the left is not the start of the string ^
followed by a plus sign.
Instead of matching a word character, you could match digits [0-9]
instead.
(?<!^\+)[0-9](?=[0-9]{4})
For example
String s = "+13334445678";
System.out.println(s.replaceAll("(?<!^\\+)[0-9](?=[0-9]{4})", "*"));
Output
+1******5678
If is is not at the start of the string, another option could be to assert what is on the left is not a plus sign that has no non whitespace char before:
(?<!(?<!\S)\+)[0-9](?=[0-9]{4})
Upvotes: 0
Reputation: 8853
If you want to match last 4 digits you can use (.{4})\\s*$
. This regex will return last 4 characters from input string irrespective of white spaces at the end.
Upvotes: 0