Skip to content

str::replacen

str methods · Strings

Level: reference · for working programmers

One line: replace with a limit — only the first n occurrences, counting from the left.

pub fn replacen<P: Pattern>(&self, pat: P, to: &str, count: usize) -> String

Stable since 1.16.0.

"aaa".replacen('a', "b", 2) is "bba". A count larger than the number of matches is fine and replaces them all; a count of 0 returns a copy with nothing replaced — and still allocates.

There is no rreplacen: the count always applies from the front. To replace the last n, find the offsets with rmatch_indices and edit with String::replace_range, working from the back so the offsets you have not used yet stay valid.

The everyday use is fixing the first occurrence only — a leading marker, the first delimiter of a line — where replacing all of them would corrupt the rest.

Example

str_replacen.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.

fn main() {
    println!("{:?}", "aaa".replacen('a', "b", 2));
    println!("{:?}", "aaa".replacen('a', "b", 9));
    println!("{:?}", "aaa".replacen('a', "b", 0));

    // Only the first delimiter, leaving the value intact.
    println!("{:?}", "key=a=b".replacen('=', ": ", 1));
    println!("{:?}", "key=a=b".replace('=', ": "));

    // The count is always from the left; for the last n, edit from the back.
    let s = "a.b.c.d";
    let mut owned = String::from(s);
    for (i, m) in s.rmatch_indices('.').take(2) {
        owned.replace_range(i..i + m.len(), "/");
    }
    println!("{owned:?}");
}

Verified output of str_replacen.rs — regenerated by tools/run_examples.py, never hand-typed.

"bba"
"bbb"
"aaa"
"key: a=b"
"key: a: b"
"a.b/c/d"

See also

str::replacen in the standard library ↗

Po polsku

Rust ustawia tu domyślność odwrotnie niż JavaScript: tam replace bez flagi /g rusza tylko pierwsze wystąpienie, a tutaj replace podmienia wszystkie i dopiero replacen jest wersją z limitem. Licznik zawsze biegnie od lewej i żadnego rreplacen nie ma — żeby ruszyć ostatnie n wystąpień, trzeba pobrać przesunięcia z rmatch_indices i edytować przez replace_range od tyłu, tak aby jeszcze niewykorzystane przesunięcia pozostały ważne; to właśnie ta linia z wynikiem "a.b/c/d". Sens całej metody widać w parze wydruków dla "key=a=b": z limitem 1 wychodzi "key: a=b" i wartość zostaje nietknięta, a bez limitu "key: a: b", czyli rozjechany rekord. Limit większy niż liczba dopasowań nie szkodzi, a 0 zwraca kopię bez zmian — ale i tak alokuje.

Szukaj po polsku: podmiana tylko pierwszego wystąpienia · limit zamian w tekście · rust replacen first occurrence · rust replace_range