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 Rust

How to Validate Email Addresses with Regex in Rust

Validating email addresses is a crucial step in many applications, such as user registration and contact forms. Using regular expressions (regex) is a common approach to validate email addresses. In this guide, we will explore how to validate email addresses with regex in Rust, a systems programming language that prioritizes safety and performance.

Quick Example

Here is a minimal example of how to validate an email address using regex in Rust:

use regex::Regex;

fn main() {
    let email = "example@example.com";
    let re = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();
    if re.is_match(email) {
        println!("Email is valid");
    } else {
        println!("Email is not valid");
    }
}

This example uses the regex crate, which can be added to your Cargo.toml file:

[dependencies]
regex = "1"

You can install the regex crate by running cargo build in your terminal.

Step-by-Step Breakdown

Let's walk through the code line by line:

  1. use regex::Regex;: We import the Regex type from the regex crate.
  2. fn main() { ... }: We define the main function, which is the entry point of our program.
  3. let email = "example@example.com";: We define a string variable email with an example email address.
  4. let re = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();: We create a new Regex instance with a pattern that matches most common email address formats. The unwrap method is used to handle any errors that may occur during pattern compilation.
  5. if re.is_match(email) { ... }: We use the is_match method to check if the email address matches the regex pattern. If it does, we print "Email is valid".

The regex pattern used in this example is a simplified version of the official email address specification (RFC 5322). It matches most common email address formats, but may not cover all possible valid formats.

Handling Edge Cases

Here are some common edge cases to consider:

Empty/Null Input

What happens if the input email address is empty or null? We can add a simple check to handle this case:

if email.is_empty() {
    println!("Email is empty");
} else if re.is_match(email) {
    println!("Email is valid");
} else {
    println!("Email is not valid");
}

Invalid Input

What if the input email address is not a string? We can use the std::error::Error trait to handle errors:

use std::error::Error;

fn validate_email(email: &str) -> Result<(), Box<dyn Error>> {
    let re = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")?;
    if re.is_match(email) {
        Ok(())
    } else {
        Err("Invalid email address".into())
    }
}

Large Input

What if the input email address is very large? We can use the std::string::String type to handle large strings:

let email = String::from("very_large_email_address@example.com");
if re.is_match(&email) {
    println!("Email is valid");
} else {
    println!("Email is not valid");
}

Unicode/Special Characters

What if the input email address contains Unicode or special characters? We can use the unicode-xid crate to handle Unicode characters:

use unicode_xid::UnicodeXID;

fn validate_email(email: &str) -> bool {
    let re = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();
    if re.is_match(email) {
        true
    } else {
        false
    }
}

let email = "example@example.com";
if validate_email(&email) {
    println!("Email is valid");
} else {
    println!("Email is not valid");
}

You can add the unicode-xid crate to your Cargo.toml file:

[dependencies]
unicode-xid = "0.2.0"

Common Mistakes

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

Mistake 1: Not handling errors

let re = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();

Corrected code:

let re = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").expect("Failed to compile regex pattern");

Mistake 2: Not checking for empty input

if re.is_match(email) {
    println!("Email is valid");
} else {
    println!("Email is not valid");
}

Corrected code:

if email.is_empty() {
    println!("Email is empty");
} else if re.is_match(email) {
    println!("Email is valid");
} else {
    println!("Email is not valid");
}

Mistake 3: Not handling large input

let email = "very_large_email_address@example.com";
if re.is_match(email) {
    println!("Email is valid");
} else {
    println!("Email is not valid");
}

Corrected code:

let email = String::from("very_large_email_address@example.com");
if re.is_match(&email) {
    println!("Email is valid");
} else {
    println!("Email is not valid");
}

Performance Tips

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

  1. Use a compiled regex pattern: Compiling the regex pattern once and storing it in a variable can improve performance.
  2. Use a cached regex pattern: If you're validating multiple email addresses with the same pattern, consider caching the compiled pattern.
  3. Use a parallel validation: If you're validating a large number of email addresses, consider using parallel processing to improve performance.

FAQ

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

A: The best regex pattern for validating email addresses is a simplified version of the official email address specification (RFC 5322).

Q: How do I handle errors when compiling a regex pattern?

A: You can use the expect method to handle errors when compiling a regex pattern.

Q: How do I handle large input email addresses?

A: You can use the std::string::String type to handle large strings.

Q: How do I handle Unicode characters in email addresses?

A: You can use the unicode-xid crate to handle Unicode characters.

Q: What is the performance impact of validating email addresses with regex?

A: The performance impact of validating email addresses with regex is generally low, but can be improved by using compiled and cached patterns, and parallel processing.

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