For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/security/code_security/static_analysis/static_analysis_rules/rust-code-quality/regex-creation-in-loops.md. A documentation index is available at /llms.txt.
This product is not supported for your selected Datadog site. ().

Metadata

ID: rust-code-quality/regex-creation-in-loops

Language: Rust

Severity: Warning

Category: Performance

Description

Constructing a Regex inside a loop causes it to be recompiled on every iteration. Regex compilation is expensive — move the regex outside the loop or use std::sync::OnceLock to compile it once.

Example

// Before — recompiled on every iteration
for item in items {
    let re = Regex::new(r"\d+").unwrap();
    if re.is_match(item) { ... }
}

// After — compiled once before the loop
let re = Regex::new(r"\d+").unwrap();
for item in items {
    if re.is_match(item) { ... }
}

Non-Compliant Code Examples

use regex::Regex;

fn search_in_for_loop(items: &[&str]) -> Vec<bool> {
    let mut results = vec![];
    for item in items {
        let re = Regex::new(r"\d+").unwrap();
        results.push(re.is_match(item));
    }
    results
}

fn search_in_while_loop(items: &[&str]) -> bool {
    let mut i = 0;
    while i < items.len() {
        let re = Regex::new(r"\d+").unwrap();
        if re.is_match(items[i]) {
            return true;
        }
        i += 1;
    }
    false
}

fn search_in_loop_block(items: &[&str]) -> bool {
    let mut i = 0;
    loop {
        if i >= items.len() { break; }
        let re = Regex::new(r"\d+").unwrap();
        if re.is_match(items[i]) { return true; }
        i += 1;
    }
    false
}

fn search_in_while_let(mut iter: impl Iterator<Item = &'static str>) -> bool {
    while let Some(item) = iter.next() {
        let re = Regex::new(r"\d+").unwrap();
        if re.is_match(item) { return true; }
    }
    false
}

Compliant Code Examples

use regex::Regex;

fn search_outside_loop(items: &[&str]) -> Vec<bool> {
    let re = Regex::new(r"\d+").unwrap();
    let mut results = vec![];
    for item in items {
        results.push(re.is_match(item));
    }
    results
}

fn no_regex_in_loop(items: &[i32]) -> i32 {
    let mut sum = 0;
    for item in items {
        sum += item;
    }
    sum
}

fn dynamic_pattern(items: &[&str]) -> Vec<bool> {
    let mut results = vec![];
    for item in items {
        let re = Regex::new(&format!("test{item}")).unwrap();
        results.push(re.is_match(item));
    }
    results
}
https://static.datadoghq.com/static/images/logos/github_avatar.svg https://static.datadoghq.com/static/images/logos/vscode_avatar.svg jetbrains

Seamless integrations. Try Datadog Code Security