屏蔽电子邮件 ID 的中心部分

Masking the centre part of the email ID

我想屏蔽电子邮件 ID,如下所示:

Input                   |   Output
qwerty@gmail.com        : qw**ty@gmail.com
helloworld@gmail.com    : he******ld@gmail.com
Whosebug@gmail.com : st*********ow@gmail.com
abcde@gmail.com         : ab*de@gmail.com
abcd@gmail.com          : a**d@gmail.com
abc@gmail.com           : a*c@gmail.com
ab@gmail.com            : a*@gmail.com
  1. 两端最多显示 2 个字符(如果可用),每端至少显示 1 个字符或仅屏蔽最后一个字符。

  2. 字符串的长度必须至少为 2 个字符 (ab@gmail.com)。

我参考了提供的一些解决方案,但无法使用这些解决方案实现第二和第三种情况。是否有可能找到修复方法?我不太精通正则表达式,所以我不确定该走哪条路。

参考资料:

工作代码位于here

考虑一种在输入字符串中替换正则表达式的方法(归功于 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;
}

然后可以将各种情况隔离到客户端代码中。在这里,我们假设“电子邮件 ID”已从电子邮件地址中删除。 (例如 qwertyinput 而不是 qwerty@gmail.com)。代码片段:

// 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);

以上,请注意 String.repeat 是在 JDK 11.

中引入的

这既不高效也不优雅,但有点可读性(尤其是 unit-tested 彻底)。它对电子邮件地址的构成进行了简单的处理。

包含另一个不使用正则表达式的解决方案 here

关于E-Mail地址中什么可以,什么不可以的有趣读物是this SO Post and this SO Post especially if you want to utilize Regular Expressions

这是完成手头任务的另一种方法:

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;
}

替代正则表达式:

"(?:(\w{2})(\w+)(\w{2}@.*)|(\w)(\w{1,2})(\w@.*)|(\w)(\w)(@.*))"

上下文中的正则表达式:

public static void main(String[] args) {
    String str = "qwerty@gmail.com\n"
            + "helloworld@gmail.com\n"
            + "Whosebug@gmail.com\n"
            + "abcde@gmail.com\n"
            + "abcd@gmail.com\n"
            + "abc@gmail.com\n"
            + "ab@gmail.com";

    // 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);
        }
    }
}

输出:

qw**ty@gmail.com
he******ld@gmail.com
st*********ow@gmail.com
ab*de@gmail.com
a**d@gmail.com
a*c@gmail.com
a*@gmail.com

注意:“字符串重复(整数计数)”仅适用于 Java 11 及以上。