Reputation: 73
I want to mask the email id as follows :
Input | Output
[email protected] : qw**[email protected]
[email protected] : he******[email protected]
[email protected] : st*********[email protected]
[email protected] : ab*[email protected]
[email protected] : a**[email protected]
[email protected] : a*[email protected]
[email protected] : a*@gmail.com
Max 2 characters at both the extremes if available, minimum 1 character at each end are to be displayed or just mask the last character.
The string has to be atleast 2 characters in length ([email protected]).
I referred some of the solutions provided, but was not able to achieve the second and third scenario using those. Is there a possibility to find a fix ? I'm not well versed with regex, so I'm not sure which way to go ahead.
references : masking of email address in java
How to i mask all string characters except for the last 4 characters in Java using parameters?
Upvotes: 0
Views: 2441
Reputation: 854
Alternative regex:
"(?:(\\w{2})(\\w+)(\\w{2}@.*)|(\\w)(\\w{1,2})(\\w@.*)|(\\w)(\\w)(@.*))"
Regex in context:
public static void main(String[] args) {
String str = "[email protected]\n"
+ "[email protected]\n"
+ "[email protected]\n"
+ "[email protected]\n"
+ "[email protected]\n"
+ "[email protected]\n"
+ "[email protected]";
// 9 matcher group in total
Pattern pattern = Pattern.compile("(?:(\\w{2})(\\w+)(\\w{2}@.*)|(\\w)(\\w{1,2})(\\w@.*)|(\\w)(\\w)(@.*))");
List<Integer> groupIndex = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
for (String email : str.split("\n")) {
Matcher matcher = pattern.matcher(email);
if(matcher.find()) {
List<Integer> activeGroupIndex = groupIndex.stream()
.filter(i -> matcher.group(i) != null)
.collect(Collectors.toList());
String prefix = matcher.group(activeGroupIndex.get(0));
String middle = matcher.group(activeGroupIndex.get(1));
String suffix = matcher.group(activeGroupIndex.get(2));
System.out.printf("%s%s%s%n", prefix, "*".repeat(middle.length()), suffix);
}
}
}
Output:
qw**[email protected]
he******[email protected]
st*********[email protected]
ab*[email protected]
a**[email protected]
a*[email protected]
a*@gmail.com
Note: "String repeat(int count)" only works from Java 11 and up.
Upvotes: 0
Reputation: 9192
Interesting reads regarding what can, and what can not be in an E-Mail Address would be this SO Post and this SO Post especially if you want to utilize Regular Expressions.
Here is another method to accomplish the task at hand:
public static String maskEMailAddress(String emailAddy) {
String id = emailAddy.substring(0, emailAddy.lastIndexOf("@"));
String domain = emailAddy.substring(emailAddy.lastIndexOf("@"));
if (id.length() <= 1) {
return emailAddy;
}
switch (id.length()) {
case 2:
id = id.substring(0,1) + "*";
break;
case 3:
id = id.substring(0,1) + "*" + id.substring(2);
break;
case 4:
id = id.substring(0,1) + "**" + id.substring(3);
break;
default:
String masks = String.join("", java.util.Collections.nCopies(id.length() - 4, "*"));
id = id.substring(0,2) + masks + id.substring(id.length() - 2);
break;
}
String address = id + domain;
return address;
}
Upvotes: 2
Reputation: 24468
Working code is located here
Consider a method that replaces a regex within an input string (credit to this answer):
String replace(String regex, String replacement, String input) {
String result = "N/A";
Matcher m = Pattern.compile(regex).matcher(input);
if (m.find()) {
int groupToReplace = 1;
result = new StringBuilder(input).replace(m.start(groupToReplace),
m.end(groupToReplace),
replacement).toString();
} else {
throw new IllegalStateException("internal error");
}
return result;
}
then the various cases can be isolated into client code. Here, we assume that the "email id" has been stripped from the email address. (e.g. qwerty
is input
and not [email protected]
). Code snippet:
// TODO: the regex strings can be compiled into proper Pattern objects
if (numChars == 2) {
regex = ".(.)";
replacement = ASTERISK;
} else if (numChars == 3) {
regex = ".(.).";
replacement = ASTERISK;
} else if (numChars == 4) {
regex = ".(..).";
replacement = ASTERISK + ASTERISK;
} else {
regex = "..(.*)..";
int numAsterisks = numChars - 4;
// requires JDK 11+
replacement = ASTERISK.repeat(numAsterisks);
}
String result = replace(regex, replacement, input);
Above, note that String.repeat
was introduced in JDK 11.
This is neither efficient nor elegant but is somewhat readable (esp. if unit-tested thoroughly). It has a simplistic treatment of what constitutes an email address.
Another solution, which doesn't use regular expressions, is included here.
Upvotes: 0