如何在 Go 中验证电子邮件地址

Riy*_*han 14 email email-validation go

我检查了 StackOverflow 并找不到任何可以回答如何在 Go Language 中验证电子邮件的问题。

经过一番研究,我想出了并根据我的需要解决了它。

我有这个正则表达式Go 函数,它工作正常:

import (
    "fmt"
    "regexp"
)

func main() {
    fmt.Println(isEmailValid("test44@gmail.com")) // true
    fmt.Println(isEmailValid("test$@gmail.com")) // true -- expected "false" 
}


// isEmailValid checks if the email provided is valid by regex.
func isEmailValid(e string) bool {
    emailRegex := regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
    return emailRegex.MatchString(e)
}
Run Code Online (Sandbox Code Playgroud)

问题是它接受了我不想要的特殊字符。我尝试使用一些来自其他语言的“正则表达式”表达式,但它在调试中抛出错误“未知转义”

谁能给我一个很好的正则表达式或任何适用于 GoLang 的快速解决方案 (pkg)?

icz*_*cza 24

标准库内置了电子邮件解析和验证,只需使用:mail.ParseAddress()

一个简单的“有效”测试:

func valid(email string) bool {
    _, err := mail.ParseAddress(email)
    return err == nil
}
Run Code Online (Sandbox Code Playgroud)

测试它:

for _, email := range []string{
    "good@exmaple.com",
    "bad-example",
} {
    fmt.Printf("%18s valid: %t\n", email, valid(email))
}
Run Code Online (Sandbox Code Playgroud)

哪些输出(在Go Playground上试试):

  good@exmaple.com valid: true
       bad-example valid: false
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你,它适用于大多数情况。不过,我对以下无效电子邮件有一些问题:“email@example.com (Joe Smith)”、“email@example” (2认同)
  • 明白了,就像在 RFC 5322 的文档中一样,它写道它正在检查域。这是[屏幕截图](https://paste.pics/e1dbbbeeee708fdd68fab6583eae4f7d),那么为什么“email@example”地址失败。 (2认同)
  • @RiyazKhan `example` 是一个有效的域,就像 `example.com` 一样。它不一定必须指定公共域,它可以是本地网络的本地域。至于“(Joe Smith)”部分:它是一条评论,可能位于电子邮件中的任何位置,请参阅[维基百科:电子邮件地址](https://en.wikipedia.org/wiki/Email_address)。相信我,“net/mail”包可以比您的自定义解决方案更好、更快、更可靠地解析电子邮件地址。 (2认同)
  • 我认为这不是有效的电子邮件“bad-example@t” (2认同)
  • @tile 根据 [RFC 5322](https://www.rfc-editor.org/rfc/rfc5322.html) 它是有效的。`t` 可以是有效的本地域名。正如上面的评论中提到的,该域可以是本地域,不一定必须是公共域。 (2认同)

Riy*_*han 16

@icza 的上述方法很好,但是,如果我们在登录/注册表单验证中使用它,很多人会输入部分或不正确的电子邮件地址,这将在生产中创建一堆无效记录。而且,谁知道我们会因此而被杀

因此,我使用正则表达式解决方案来验证标准电子邮件

这是代码:

func isEmailValid(e string) bool {
    emailRegex := regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
    return emailRegex.MatchString(e)
}
Run Code Online (Sandbox Code Playgroud)

测试用例:

fmt.Println(isEmailValid("test44@gmail.com"))         // true 
fmt.Println(isEmailValid("bad-email"))               // false
fmt.Println(isEmailValid("test44$@gmail.com"))      // false
fmt.Println(isEmailValid("test-email.com"))        // false
fmt.Println(isEmailValid("test+email@test.com"))  // true
Run Code Online (Sandbox Code Playgroud)

  • 即使是最烂的答案也承认 $ 被接受。/sf/answers/143465731/ https://play.golang.org/p/iI2GeEmHRzE (3认同)
  • 相信我,“mail.ParseAddress()”比您能做得更好。它接受本地域,但告诉我,您确定“this-surely-doesnt-exist-just-showing-this-will-pass@nowhereland.cum”是比“good@mydomain”更好的“有效”电子邮件吗?无论如何,您都应该实施并要求电子邮件验证。否则,简单地验证电子邮件地址在语法上是否正确几乎没有任何价值。 (2认同)