如何验证电子邮件地址?

372

请参考以下链接,可能会对您有所帮助: https://dev59.com/ymcs5IYBdhLWcg3wUCUI - Hiren Patel
1
@user2757064 嗯,这个问题应该会对你链接的那个问题有所帮助。那个问题是在这个问题之后3年提出的。 :) - Sufian
如果要进行简单的检查:if(!Patterns.EMAIL_ADDRESS.matcher(editTextEmail.getText().toString()).matches()){ //show toast:enter valid email } - AG-Developer
35个回答

1137

另一个选项是从API Level 8开始内置的Patterns:

public final static boolean isValidEmail(CharSequence target) {
  if (TextUtils.isEmpty(target)) {
    return false;
  } else {
    return android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
  }
}

Patterns.java可查看源代码

或者

@AdamvandenHoven提供了一行解决方案:

public final static boolean isValidEmail(CharSequence target) {
  return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}

32
+1,但我更喜欢用 TextUtils.isEmpty(target) 替换 (target == null) :) - Houcine
42
像这样的答案就是我为什么不喜欢显示被接受的答案在顶部,而不是拥有最多票数的答案。 - Jeshurun
13
把这段代码合并成一行岂不更易读:return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches(); - Adam van den Hoven
1
@Houcine,确实如此,但上面的方法返回布尔值,因此当它为false时我们没有那个信息。无论如何,我们可以在函数内部(必须在UI线程中运行)烤面包或更新UI。对于像我这样的人,他们通过编程方式获取并且没有任何用户交互来验证电子邮件的人,我们可以坚持使用“== null”,在大多数情况下可能节省几个时钟周期。 - A.J.
3
请注意,此匹配器将email@111.222.333.44444视为有效的电子邮件地址。 - Joaquin Iurchuk
显示剩余17条评论

108

下一个模式用于K-9邮件:

public static final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile(
          "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
          "\\@" +
          "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
          "(" +
          "\\." +
          "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
          ")+"
      );

您可以使用函数

private boolean checkEmail(String email) {
        return EMAIL_ADDRESS_PATTERN.matcher(email).matches();
}

79
为什么不使用 android.util.Patterns.EMAIL_ADDRESS - Sergey Metlov
10
因为它仅存在于 API Level 8 及更高版本。 - Andrei Buneyeu
这对我帮助很大,谢谢你提供简单的答案并点赞。 :) - Deepthi
FYI:在字符类中,元字符要少得多,并且当连字符放在边界时会自动转义,您可以将第一个类简化为[a-zA-Z0-9+._%-],其他类简化为[a-zA-Z0-9-] - Robin
只有在电子邮件语法与电子邮件相同的情况下,才会返回true。我尝试从“@gmail.com”中删除“i”,它将返回true。在“@yaho.com”中也是如此。 - RoCkDevstack
@SergeyMetlov,由于某种原因,android.util.Patterns.EMAIL_ADDRESS在JUnit测试中返回null。 - Nishant Shah

76
自API 8(Android 2.2)以来,有一个模式:android.util.Patterns.EMAIL_ADDRESS。因此,您可以使用它来验证您的EmailString: http://developer.android.com/reference/android/util/Patterns.html
private boolean isValidEmail(String email) {
    Pattern pattern = Patterns.EMAIL_ADDRESS;
    return pattern.matcher(email).matches();
}

如果电子邮件地址有效,则返回true。

更新: 此模式源代码为:

public static final Pattern EMAIL_ADDRESS
    = Pattern.compile(
        "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
        "\\@" +
        "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
        "(" +
            "\\." +
            "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
        ")+"
    );

参考:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/util/Patterns.java

因此,您可以构建它以与API <8兼容。


1
"[a-zA-Z0-9\+\.\_\%\-\+]" 为什么重复两次使用 '+' 符号? - Denis Sologub

69

我们现在拥有一个简单的电子邮件模式匹配器。

Java:

 private static boolean isValidEmail(String email) {
        return !TextUtils.isEmpty(email) && android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
    }

Kotlin函数:

 private fun isValidEmail(email: String): Boolean {
        return !TextUtils.isEmpty(email) && Patterns.EMAIL_ADDRESS.matcher(email).matches()
    }

Kotlin 扩展:

fun String.isValidEmail() =
    !TextUtils.isEmpty(this) && Patterns.EMAIL_ADDRESS.matcher(this).matches()

54

不要使用正则表达式。

显然,以下是一个正则表达式,它能正确验证符合RFC 2822标准的大多数电子邮件地址(但仍会失败于像"user@gmail.com.nospam"这样的地址,也和org.apache.commons.validator.routines.EmailValidator一样)。

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

验证电子邮件地址可能最简单的方法是向提供的地址发送确认电子邮件,如果它被退回,那么它就是无效的。

如果您想执行一些基本检查,您可以仅检查它是否符合*@*的形式。

如果您有一些特定业务逻辑的验证要求,则可以使用正则表达式来执行该操作,例如必须是gmail.com帐户之类的东西。


5
我知道这个答案已经有两年了,但是当我在regexr.com上尝试使用这个正则表达式时,它能够验证 user@gmail.com.nospam 甚至更长的域名后缀(TLD)例如 .museum。我错过了什么吗?我不想因未能验证用户有效电子邮件地址而阻止他们使用我的服务,但这个正则表达式似乎对我能想到的所有东西都有效。 - Bob Vork
143
我有点困惑,为什么你在回答之初会说“不要使用正则表达式”,但随后又提供了一个正则表达式。 - howettl
9
请继续阅读。下面的更好解决方案不使用正则表达式。 - loeschg
2
@Glen。这是否适用于Android的Pattern.EMAIL_ADDRESS?https://developer.android.com/reference/android/util/Patterns.html#EMAIL_ADDRESS - zulkarnain shah
另外,如果您想知道给定域名是否有效,则可以向Google的DNS服务发出DNS查询请求。例如:https://dns.google/resolve?name=brosoft.com.ar&type=mx - Nico
显示剩余2条评论

25

使用简单的一行代码进行电子邮件验证

public static boolean isValidEmail(CharSequence target) {
    return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}

使用方式如下...

if (!isValidEmail(yourEdittext.getText().toString()) {
    Toast.makeText(context, "your email is not valid", 2000).show();
}

21

您可以编写如下所示的 Kotlin 扩展:

fun String.isValidEmail() =
        isNotEmpty() && android.util.Patterns.EMAIL_ADDRESS.matcher(this).matches()

然后像这样调用它:

email.isValidEmail()

1
谁是“Patterns”? - Jemshit Iskenderov
android.util.Patterns - Danilo Lemes
该Util模式接受"abcde@gmail.c"。 - NullPointerExcepzion

16

这是Android Studio的建议:

public static boolean isEmailValid(String email) {
    return !(email == null || TextUtils.isEmpty(email)) && android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
}

1
空值检查 email == null 是多余的,因为TextUtils会在内部检查它。 - Volodymyr
@VolodymyrKhodonovych 你说得对,但是空值检查是在OR状态下完成的,不这样做可能会导致将电子邮件传递给matcher()方法时出现NPE。 - Lampione

12

使用android:inputType="textEmailAddress"如下:

       <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="email"
        android:inputType="textEmailAddress"
        android:id="@+id/email"
        />

并且:

       boolean isEmailValid(CharSequence email) {
        return android.util.Patterns.EMAIL_ADDRESS.matcher(email)
                .matches();
      }

11

你可以使用正则表达式来实现。类似以下内容。

Pattern pattern = Pattern.compile(".+@.+\\.[a-z]+");
String email = "xyz@xyzdomain.com";
Matcher matcher = pattern.matcher(email);
boolean matchFound = matcher.matches();
注意:检查上面给出的正则表达式,不要直接使用它。

3
以下合法的电子邮件地址“Example Guy”<guy@example.com>将导致此验证失败。虽然从技术上讲,你可以使用正则表达式验证电子邮件地址,但这样做有点荒谬。 - Cory Petosky
1
那不仅仅是一个电子邮件地址。 - Brill Pappin
这也匹配 "guy@@example. com"(用户按两次相同的键并且某些键盘在句号后添加空格并不意外)。这也不支持Unicode字符。以下是一些不寻常但有效的地址示例:https://en.wikipedia.org/wiki/International_email - tiktak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接