masking of email address in java
Your Look-ahead is kind of complicated. Try this code :
public static void main(String... args) throws Exception {
String s = "[email protected]";
s= s.replaceAll("(?<=.{3}).(?=.*@)", "*");
System.out.println(s);
}
O/P :
nil********@gmail.com
Your look-ahead (?=[^@]*?.@)
requires at least 1 character to be there in front of @
(see the dot before @
).
If you remove it, you will get all the expected symbols replaced:
(?<=.{3}).(?=[^@]*?@)
Here is the regex demo (replace with *
).
However, the regex is not a proper regex for the task. You need a regex that will match each character after the first 3 characters up to the first @
:
(^[^@]{3}|(?!^)\G)[^@]
See another regex demo, replace with $1*
. Here, [^@]
matches any character that is not @
, so we do not match addresses like [email protected]
. Only those emails will be masked that have 4+ characters in the username part.
See IDEONE demo:
String s = "[email protected]";
System.out.println(s.replaceAll("(^[^@]{3}|(?!^)\\G)[^@]", "$1*"));
If you're bad at regular expressions, don't use them :) I don't know if you've ever heard the quote:
Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.
(source)
You might get a working regular expression here, but will you understand it today? tomorrow? in six months' time? And will your colleagues?
An easy alternative is using a StringBuilder
, and I'd argue that it's a lot more straightforward to understand what is going on here:
StringBuilder sb = new StringBuilder(email);
for (int i = 3; i < sb.length() && sb.charAt(i) != '@'; ++i) {
sb.setCharAt(i, '*');
}
email = sb.toString();
"Starting at the third character, replace the characters with a *
until you reach the end of the string or @
."
(You don't even need to use StringBuilder
: you could simply manipulate the elements of email.toCharArray()
, then construct a new string at the end).
Of course, this doesn't work correctly for email addresses where the local part is shorter than 3 characters - it would actually then mask the domain.