I am trying to mask email address with "*" but I am bad at regex.
input :
output : nil********@gmail.comMy 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*")); 8 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 2 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** 3 //In Kotlin
val email = ""
val maskedEmail = email.replace(Regex("(?<=.{3}).(?=.*@)"), "*") 2 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; }