Strings and Text Processing

replace() and replacen()

The .replace() and .replacen() methods on str search for occurrences of a pattern (&str, char, &[char], or a char predicate closure) and return a newly allocated String with the matched substrings substituted.

Signatures

pub fn replace<P: Pattern>(&self, from: P, to: &str) -> String
pub fn replacen<P: Pattern>(&self, from: P, to: &str, count: usize) -> String
  • s.replace(from, to) replaces every non-overlapping occurrence of from with to.
  • s.replacen(from, to, count) replaces at most the first count occurrences of from with to and copies the remainder of s unchanged.

Neither method modifies self in place; both return a new String.

Replacing All vs. Replacing the First $N$ Matches

fn main() {
    let path = "a/b/c/d";

    // Replace all '/' with "::":
    let module_path = path.replace('/', "::");

    // Replace only the first 2 '/' occurrences:
    let partial = path.replacen('/', "::", 2);

    println!("All replaced:     {module_path}");
    println!("First 2 replaced: {partial}");
}
All replaced:     a::b::c::d
First 2 replaced: a::b::c/d

Replacing Character Classes Using a Predicate Closure

Because from accepts any Pattern—including a closure FnMut(char) -> bool or a slice of characters &[char]—you can redact or sanitize entire character classes with .replace():

fn main() {
    let log_line = "user=alice pin=4829 token=9910";

    // Replace every ASCII digit with '*':
    let redacted = log_line.replace(|ch: char| ch.is_ascii_digit(), "*");

    println!("Redacted: {redacted}");
}
Redacted: user=alice pin=**** token=****

Deleting Substrings by Passing "" as the Replacement

Passing an empty string "" as the second argument deletes all (or the first count) occurrences of a substring:

fn main() {
    let formatted_number = "1,234,567";
    let clean = formatted_number.replace(',', "");
    println!("Cleaned: {clean}");
}
Cleaned: 1234567