掩盖电子邮件ID的中心部分

问题描述

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

Input                   |   Output
qwerty@gmail.com        : qw**ty@gmail.com
helloworld@gmail.com    : he******ld@gmail.com
stackoverflow@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)。

我引用了所提供的一些解决方案,但使用这些解决方案无法实现第二种和第三种情况。有可能找到解决办法吗?我对regex不太了解,所以不确定前进的方向。

参考: masking of email address in java

How to i mask all string characters except for the last 4 characters in Java using parameters?

解决方法

有关在电子邮件地址中可以做什么和不能做什么的有趣内容是this SO Postthis SO Post,特别是如果您想使用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;
}
,

工作代码位于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中引入的。

这既不高效也不美观,但是有点可读(特别是如果进行了彻底的单元测试)。它对构成电子邮件地址的方式进行了简单处理。

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

,

以下给出的是非正则表达式(拆分除外)解决方案:

public class Main {
    public static void main(String[] args) {
        // Test strings
        String[] arr = { "qwerty@gmail.com","helloworld@gmail.com","stackoverflow@gmail.com","ab@gmail.com","abc@gmail.com","abcd@gmail.com","abcde@gmail.com","a@gmail.com" };
        char maskChar = '*';

        for (String s : arr) {
            // Split on '@'
            String[] parts = s.split("@");

            // Length of part before '@'
            int len = parts[0].length();

            StringBuilder sb = new StringBuilder();

            if (len >= 2) {
                if (len >= 5) {
                    // Add the first 2 characters
                    sb.append(s.substring(0,2));
                    // Since 2 characters in the beginning and 2 at the end have to be retained,the
                    // no. of iterations will be 4 less than the length
                    for (int i = 1; i <= len - 4; i++) {
                        sb.append(maskChar);
                    }
                    // Add the last 2 characters
                    sb.append(s.substring(len - 2));
                } else if (len > 2) {
                    // Add the first character
                    sb.append(s.charAt(0));
                    // Since 1 characters in the beginning and 1 at the end have to be retained,the
                    // no. of iterations will be 2 less than the length
                    for (int i = 1; i <= len - 2; i++) {
                        sb.append(maskChar);
                    }
                    // Add the last character
                    sb.append(s.substring(len - 1));
                } else {
                    // len == 2
                    sb.append(s.charAt(0)).append(maskChar);
                }
            } else {
                System.out.println("Invalid ID");
            }
            System.out.println(sb);
        }
    }
}

输出:

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

替代正则表达式:

"(?:(\\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"
            + "stackoverflow@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及更高版本。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...