Skip to content

Instantly share code, notes, and snippets.

@emmaly
Last active August 25, 2023 00:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emmaly/5f10d1ba89d491900c56e78f8054ae51 to your computer and use it in GitHub Desktop.
Save emmaly/5f10d1ba89d491900c56e78f8054ae51 to your computer and use it in GitHub Desktop.
Email Regular Expression

Email RegEx

Go

var emailAddressRE = regexp.MustCompile(`^(?i)(?:(?:\"[^\"]+\")|[a-z0-9!#$%&'*+\-\/=?^_` + "`" + `{|}~]+(?:\.[a-z0-9!#$%&'*+\-\/=?^_` + "`" + `{|}~]+)*)@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$`)
if !emailAddressRE.MatchString("emmaly@example.com") {
  panic("oops")
}

RE2, PCRE2, PCRE, Java 8

^(?i)(?:(?:\"[^\"]+\")|[a-z0-9!#$%&'*+\-\/=?^_`{|}~]+(?:\.[a-z0-9!#$%&'*+\-\/=?^_`{|}~]+)*)@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$

ECMAScript/JavaScript

/^(?:(?:\"[^\"]+\")|[a-z0-9!#$%&'*+\-\/=?^_`{|}~]+(?:\.[a-z0-9!#$%&'*+\-\/=?^_`{|}~]+)*)@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i

.NET

^(?i)(?:(?:""[^""]+"")|[a-z0-9!#$%&'*+\-\/=?^_`{|}~]+(?:\.[a-z0-9!#$%&'*+\-\/=?^_`{|}~]+)*)@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$

Status

Seems to validate in basically all typical situations, but it won't validate emojis even when they're valid. See below for examples.

πŸ‘ Rejected for RHS errors

❌   emmaly@.example.com    (RHS starts with period)
❌   emmaly@example.com.    (RHS ends with period)
❌   emmaly@example..com    (RHS has two consecutive periods)
❌   emmaly@e@xample.com    (address contains two at-symbols)

πŸ‘ Rejected for LHS errors

❌   .emmaly@example.com    (LHS starts with period)
❌   emmaly.@example.com    (LHS ends with period)
❌   emmaly@@example.com    (address contains two at-symbols)

πŸ‘ Quoting the above LHS rejects will allow them to validate

βœ…   "emmaly."@example.com  (quoted LHS is valid)
βœ…   ".emmaly"@example.com  (quoted LHS is valid)
βœ…   "emmaly@"@example.com  (quoted LHS is valid)

πŸ‘ These are valid as expected

βœ…   emmaly@example.io      (valid)
βœ…   emma.ly@example.com    (valid)
βœ…   emmaly@example.com     (valid)
βœ…   emmaly@example.co.m    (valid, though no TLDs are 1-character long)
βœ…   emmaly@exa.mple.com    (valid)

πŸ€¦β€β™€οΈ Fails to validate, but it's valid

❌   emmaly@πŸ˜‰.tld         (but emoji domains are technically valid)

πŸ‘ Validates because it's the punycode version of the above

βœ…   emmaly@xn--n28h.tld    (punycode version of emoji domain is valid)

❔ RFC 5322 says this is invalid without quotation marks; the pattern rejects it

❌   πŸ˜‰@example.com        (non-ASCII on LHS unless quoted is technically invalid)

(but I think we should consider treating it as valid...)

πŸ‘ It's valid if it's quoted; the pattern correctly validates it

βœ…   "πŸ˜‰"@example.com      (quoted LHS validly contains non-ASCII)
package main
import (
"fmt"
"regexp"
)
var emailAddressRE = regexp.MustCompile(`^(?i)(?:(?:\"[^\"]+\")|[a-z0-9!#$%&'*+\-\/=?^_` + "`" + `{|}~]+(?:\.[a-z0-9!#$%&'*+\-\/=?^_` + "`" + `{|}~]+)*)@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$`)
func main() {
emailAddresses := []string{
`emmaly@.example.com`,
`emmaly@example.com.`,
`emmaly@example..com`,
`emmaly@e@xample.com`,
``,
`.emmaly@example.com`,
`emmaly.@example.com`,
`emmaly@@example.com`,
``,
`"emmaly."@example.com`,
`".emmaly"@example.com`,
`"emmaly@"@example.com`,
``,
`emmaly@example.io`,
`emma.ly@example.com`,
`emmaly@example.com`,
`emmaly@example.co.m`,
`emmaly@exa.mple.com`,
``,
`emmaly@πŸ˜‰.tld`,
``,
`emmaly@xn--n28h.tld`,
``,
`πŸ˜‰@example.com`,
``,
`"πŸ˜‰"@example.com`,
}
for _, emailAddress := range emailAddresses {
if emailAddress == "" {
fmt.Println()
continue
}
fmt.Printf("%t\t%s\n", emailAddressRE.MatchString(emailAddress), emailAddress)
}
}
// false emmaly@.example.com
// false emmaly@example.com.
// false emmaly@example..com
// false emmaly@e@xample.com
//
// false .emmaly@example.com
// false emmaly.@example.com
// false emmaly@@example.com
//
// true "emmaly."@example.com
// true ".emmaly"@example.com
// true "emmaly@"@example.com
//
// true emmaly@example.io
// true emma.ly@example.com
// true emmaly@example.com
// true emmaly@example.co.m
// true emmaly@exa.mple.com
//
// false emmaly@πŸ˜‰.tld
//
// true emmaly@xn--n28h.tld
//
// false πŸ˜‰@example.com
//
// true "πŸ˜‰"@example.com
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment