【问题标题】:How to tell if a random string is an email address or something else如何判断随机字符串是电子邮件地址还是其他东西
【发布时间】:2013-08-27 11:14:30
【问题描述】:

我认为以前没有人问过这个问题......我当然找不到有这个要求的东西。

背景

有一个 API 可以返回人员的 ID。一般来说,ID 应该被视为区分大小写......但如果 ID 实际上是他们的电子邮件地址......并且您正在与此 API 的不太出色的实现交谈,该 API 返回其电子邮件地址的混合大小写版本,有很多乐趣......

所以您正在与一种实现对话...它会返回 URL,例如 ID,例如

  • http://foo.bar.com/blahblahblah

接下来您可能正在与另一个实现对话...它会返回一些不明显的 ID,例如

  • as€jlhdésdj678hjghas7t7qhjdhg£

您可能正在与一个不错的实现交谈,它会为您返回一个不错的小写电子邮件地址:

  • bob.mcspam@acme.org

或者您可能正在与返回完全相同 ID 的不太出色的实现交谈

  • bob.mcspam@ACME.org

RFC 2821 规定只有邮箱区分大小写,但利用区分大小写会导致大量互操作问题...

我想要做的是识别作为电子邮件的字符串并强制域为小写。识别类似字符串的 URI 更容易,因为方案是 httphttps,我只需要将域名小写,这样更容易解析。

问题

如果给定一个由外部服务提供的字符串,我是否可以使用一个测试来确定该字符串是否是电子邮件地址,以便我可以强制域名为小写?

遗漏一小部分电子邮件地址而不使域名小写是可以接受的。 (允许假阴性)

如果字符串的一部分不是电子邮件地址的域部分,则将其强制为小写是不可接受的。 (不允许误报)

 更新

请注意,此问题与 thisthis 略有不同,因为在这两个问题的上下文中,您已经知道字符串应该是电子邮件地址

在这个问题的上下文中,我们不知道字符串是电子邮件地址还是其他东西......这使得这个问题与众不同

【问题讨论】:

  • 除了检查域是否存在并且在其 DNS 条目中有电子邮件服务器之外,为什么不能使用正则表达式来检查语法上合法的电子邮件地址?很多飞来飞去的人。
  • Verify email in Java的可能重复
  • @radai 好吧,我不想在评估此代码的代码路径上调用 DNS 查询,因为这会引入问题...特别是运行此代码的服务器可能不是能够验证返回的 ID 中的域名。所以检查 DNS 条目已经结束了
  • dns 验证是一个额外的步骤,但除了正则表达式之外,我真的看不到任何其他方法

标签: java email


【解决方案1】:

-试试下面的代码,可能对你有帮助。

public class EmailCheck {

    public static void main(String[] args){


        String email = "vivek.mitra@gmail.com";
        Pattern pattern = Pattern.compile("[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}");
        Matcher mat = pattern.matcher(email);

        if(mat.matches()){

            System.out.println("Valid email address");
        }else{

            System.out.println("Not a valid email address");
        }
    }

}

- 还可以看看这个网站,它显示了另一个使用regular expression 的更深入的验证。 Deeper validation using regular expression

【讨论】:

  • 请注意,"ping @ pong!"@[1.2.3.4] 是您的代码无法正确识别的有效电子邮件地址......现在它也是一个有效的电子邮件地址,不需要在 @ 之后的位小写,但是那是一个不同的问题。使用正则表达式来识别电子邮件地址是一种反模式
【解决方案2】:

您可以使用以下来验证电子邮件;

String email ="nbjvkj@kn.com"
Pattern p = Pattern.compile(".+@.+\\.[a-z]+");
Matcher m = p.matcher(email);
boolean matchFound = m.matches();
if (matchFound) {
    //your work here
}

【讨论】:

  • 该正则表达式在@ 符号之后匹配太多,因为它应该只匹配有效构造的域名。
【解决方案3】:

感谢@Dukeling

private static toLowerCaseIfEmail(String string) {
    try {
        new InternetAddress(string, true);
    } catch (AddressException e) {
        return string;
    }
    if (string.trim().endsWith("]")) {
        return string;
    }
    int lastAt = string.lastIndexOf('@');
    if (lastAt == -1) {
        return string;
    }
    return string.substring(0,lastAt)+string.substring(lastAt).toLowerCase();
}

应该,据我所知,做必要的事情。

更新

由于前一个忽略了在最后一个 @... 之后出现 (comment) 语法的可能性...这让我们面对现实,如果我们看到它们应该快速退出并返回未修改的字符串

private static toLowerCaseIfEmail(String string) {
    try {
        new InternetAddress(string, true);
    } catch (AddressException e) {
        return string;
    }
    int lastAt = string.lastIndexOf('@');
    if (lastAt == -1 
        || string.lastIndexOf(']') > lastAt
        || string.lastIndexOf(')' > lastAt) {
        return string;
    }
    return string.substring(0,lastAt)+string.substring(lastAt).toLowerCase();
}

【讨论】:

  • 这真的是答案吗??
  • 是的,因为 RFC 2821 中的电子邮件规范很多比您想象的要陌生,使用标准 Java API 的最佳方法是让符合规范的解析器解析请求并保释路由路径地址(因此endsWith("]")
  • 我打赌@StephenConnolly 已经发送了很多电子邮件。他知道痛苦。
  • 当然我的尝试不处理电子邮件地址中的 cmets...john."M@c"."Smith!"(coolguy)@(thefantastic)[1.2.3.4](onlythebest) 也是一个有效的电子邮件地址...但它可以安全地忽略如果不是使用endsWith("[") 保释,则检查indexOf(']') < lastAt 因为这将指示一个不需要 小写的电子邮件地址,因为[] 仅用于IP 地址
【解决方案4】:

我的建议是使用:

org.apache.commons.validator.routines.EmailValidator.isValid(value::String)

https://commons.apache.org/proper/commons-validator/apidocs/org/apache/commons/validator/routines/EmailValidator.html

【讨论】:

  • Handy 类,但文档给出了此免责声明:"This implementation is not guaranteed to catch all possible errors in an email address. "
【解决方案5】:
        Pattern pattern = Pattern.compile("^[A-Za-z0-9._]{1,16}+@{1}+[a-z]{1,7}\\.[a-z]{1,3}$");
        Matcher mail = pattern.matcher(your_mail);

        if (mail.find()) {
            System.out.println("True");
        } else {
            System.out.println("False");
        }

【讨论】:

  • 你能提供一个解释来配合你的答案吗? ta
  • 对于myname+classifier@gmail.com 之类的电子邮件地址或任何花哨的邮箱标识符(例如"name with spaces"@example.com 是一个有效的电子邮件地址(即使是一个愚蠢的)并且不会通过您的正则表达式
  • 哦,我的实际 gmail 电子邮件地址也失败了,因为我的邮箱标识符是 21 个字符长
猜你喜欢
  • 2010-09-09
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
  • 1970-01-01
  • 2014-07-07
  • 1970-01-01
  • 2021-06-22
  • 2023-03-10
相关资源
最近更新 更多