Masking of Email Address in Java
I Am Trying to Mask Email Address with "*" but I Am Bad at Regex. Input: Output: Nil********@Gmail. Com My Code Is String maskedEmail = Email. replaceAll("(?...
I am trying to mask email address with "*" but I am bad at regex.
input :
output : nil********@gmail.com
My code is
String maskedEmail = email.replaceAll("(?<=.{3}).(?=[^@]*?.@)", "*");
but its giving me output nil******* I am not getting whats getting wrong here. Why last character is not converted?
Also can someone explain meaning all these regex
6 Answers
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 . Only those emails will be masked that have 4+ characters in the username part.
See IDEONE demo:
String s = "";
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.
Your Look-ahead is kind of complicated. Try this code :
public static void main(String... args) throws Exception {
String s = "";
s= s.replaceAll("(?<=.{3}).(?=.*@)", "*");
System.out.println(s);
}
O/P :
nil********@gmail.com
I like this one because I just want to hide 4 characters, it also dynamically decrease the hidden chars to 2 if the email address is too short:
public static String maskEmailAddress(final String email) {
final String mask = "*****";
final int at = email.indexOf("@");
if (at > 2) {
final int maskLen = Math.min(Math.max(at / 2, 2), 4);
final int start = (at - maskLen) / 2;
return email.substring(0, start) + mask.substring(0, maskLen) + email.substring(start + maskLen);
}
return email;
}
Sample outputs:
> my****
> i**
//In Kotlin
val email = ""
val maskedEmail = email.replace(Regex("(?<=.{3}).(?=.*@)"), "*")
public static string GetMaskedEmail(string emailAddress)
{
string _emailToMask = emailAddress;
try
{
if (!string.IsNullOrEmpty(emailAddress))
{
var _splitEmail = emailAddress.Split(Char.Parse("@"));
var _user = _splitEmail[0];
var _domain = _splitEmail[1];
if (_user.Length > 3)
{
var _maskedUser = _user.Substring(0, 3) + new String(Char.Parse("*"), _user.Length - 3);
_emailToMask = _maskedUser + "@" + _domain;
}
else
{
_emailToMask = new String(Char.Parse("*"), _user.Length) + "@" + _domain;
}
}
}
catch (Exception) { }
return _emailToMask;
}