Try it yourself with our free Regex Tester tool — runs entirely in your browser, no signup needed.

How to Validate email addresses with regex in Swift

How to Validate Email Addresses with Regex in Swift

Validating email addresses is a crucial step in many applications, from user registration to contact forms. In this article, we will explore how to use regular expressions (regex) to validate email addresses in Swift. We will provide a quick example, a step-by-step breakdown, and cover common edge cases, mistakes, and performance tips.

Quick Example

import Foundation

func isValidEmail(_ email: String) -> Bool {
    let emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
    let predicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
    return predicate.evaluate(with: email)
}

// Example usage:
let email = "john.doe@example.com"
if isValidEmail(email) {
    print("Valid email")
} else {
    print("Invalid email")
}

This code defines a function isValidEmail that takes a string as input and returns a boolean indicating whether the email is valid. The function uses a regex pattern to match the email address.

Step-by-Step Breakdown

Let's break down the code line by line:

  1. import Foundation: We import the Foundation framework, which provides the NSPredicate class used for regex matching.
  2. func isValidEmail(_ email: String) -> Bool: We define a function isValidEmail that takes a string as input and returns a boolean.
  3. let emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$": We define the regex pattern as a string. This pattern matches most common email address formats.
    • ^ matches the start of the string.
    • [a-zA-Z0-9._%+-]+ matches one or more alphanumeric characters, dots, underscores, percent signs, plus signs, or hyphens.
    • @ matches the @ symbol.
    • [a-zA-Z0-9.-]+ matches one or more alphanumeric characters, dots, or hyphens.
    • \. matches a period (escaped with a backslash because . has a special meaning in regex).
    • [a-zA-Z]{2,} matches the domain extension (it must be at least 2 characters long).
    • $ matches the end of the string.
  4. let predicate = NSPredicate(format: "SELF MATCHES %@", emailRegex): We create an NSPredicate instance with the regex pattern. The SELF keyword refers to the input string.
  5. return predicate.evaluate(with: email): We evaluate the predicate with the input email address and return the result.

Handling Edge Cases

Here are some common edge cases to consider:

Empty/Null Input

let email = ""
if isValidEmail(email) {
    print("Valid email") // This will not be printed
} else {
    print("Invalid email") // This will be printed
}

The function correctly returns false for an empty input.

Invalid Input

let email = "invalid email"
if isValidEmail(email) {
    print("Valid email") // This will not be printed
} else {
    print("Invalid email") // This will be printed
}

The function correctly returns false for an invalid input.

Large Input

let email = "a".repeating(1000) + "@example.com"
if isValidEmail(email) {
    print("Valid email") // This will not be printed
} else {
    print("Invalid email") // This will be printed
}

The function correctly returns false for a large input that exceeds the maximum allowed length.

Unicode/Special Characters

let email = "john.doe@example.é"
if isValidEmail(email) {
    print("Valid email") // This will be printed
} else {
    print("Invalid email")
}

The function correctly returns true for an email address with Unicode characters.

Common Mistakes

Here are three common mistakes developers make when validating email addresses with regex in Swift:

Mistake 1: Using a too-simplistic regex pattern

let emailRegex = "^[a-zA-Z0-9]+@[a-zA-Z0-9]+$"

This pattern does not match many valid email address formats.

Corrected code:

let emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"

Mistake 2: Not escaping special characters

let emailRegex = "^([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$)"

This pattern is incorrect because the dot (.) is not escaped.

Corrected code:

let emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"

Mistake 3: Not using the NSPredicate class

let emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
if email.range(of: emailRegex, options: .regularExpression) != nil {
    print("Valid email")
} else {
    print("Invalid email")
}

This code does not use the NSPredicate class, which provides a more convenient and efficient way to perform regex matching.

Corrected code:

let emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
let predicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
if predicate.evaluate(with: email) {
    print("Valid email")
} else {
    print("Invalid email")
}

Performance Tips

Here are three practical performance tips for validating email addresses with regex in Swift:

  1. Use a compiled regex pattern: Instead of creating a new NSPredicate instance every time you need to validate an email address, create a compiled regex pattern and reuse it.
let emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
let predicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
  1. Use a cached regex pattern: If you need to validate a large number of email addresses, consider caching the compiled regex pattern to avoid recompiling it every time.
let emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
let predicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
// Cache the predicate instance
let cachedPredicate = predicate
  1. Avoid using regex for simple validation: If you only need to validate a simple email address format, consider using a simpler approach that does not involve regex.
let email = "john.doe@example.com"
if email.contains("@") && email.contains(".") {
    print("Valid email")
} else {
    print("Invalid email")
}

FAQ

Q: What is the best regex pattern for validating email addresses?

A: The regex pattern used in this article is a good starting point, but you may need to adjust it depending on your specific requirements.

Q: Can I use this regex pattern for validating email addresses in other programming languages?

A: Yes, the regex pattern is language-agnostic, but you may need to adjust the syntax and escaping rules depending on the language.

Q: How can I improve the performance of email address validation?

A: Use a compiled regex pattern, cache the predicate instance, and avoid using regex for simple validation.

Q: Can I use this regex pattern for validating email addresses with non-ASCII characters?

A: Yes, the regex pattern used in this article supports Unicode characters.

Q: How can I handle edge cases when validating email addresses?

A: Use the techniques described in the "Handling Edge Cases" section to handle common edge cases such as empty/null input, invalid input, large input, and Unicode/special characters.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp