Skip to content

str::strip_suffix

str methods · Strings

Level: reference · for working programmers

One line: Removes the suffix once and returns Some(rest), or None — the mirror of strip_prefix.

pub fn strip_suffix<P: Pattern>(&self, suffix: P) -> Option<&str>
where
    for<'a> P::Searcher<'a>: ReverseSearcher<'a>,

Stable since 1.45.0.

Same contract at the other end: one occurrence, and a None you have to handle.

The everyday jobs are dropping a known extension and dropping a line ending. For the second, line.strip_suffix('\n') tells you whether the line was terminated, which trim_end cannot — and that difference matters when a truncated final line is an error rather than a formatting detail.

For filenames, prefer Path: strip_suffix(".rs") is a byte comparison that does not know about case-insensitive filesystems or about .tar.gz.

Chained with strip_prefix in an and_then, it is the honest unquoter — both ends required, or nothing.

Example

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

fn main() {
    println!("{:?}", "main.rs".strip_suffix(".rs"));
    println!("{:?}", "main.py".strip_suffix(".rs"));

    // Line endings: this reports whether the line was terminated.
    for raw in ["done\n", "done"] {
        println!("{:<8} -> {:?}", format!("{raw:?}"), raw.strip_suffix('\n'));
    }

    // Balanced unquoting: both ends, or nothing.
    for q in ["\"hi\"", "\"hi", "hi"] {
        let inner = q.strip_prefix('"').and_then(|s| s.strip_suffix('"'));
        println!("{:<8} -> {inner:?}", format!("{q:?}"));
    }

    // Once, not repeatedly.
    println!("{:?}", "a///".strip_suffix('/'));
    println!("{:?}", "a///".trim_end_matches('/'));
}

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

Some("main")
None
"done\n" -> Some("done")
"done"   -> None
"\"hi\"" -> Some("hi")
"\"hi"   -> None
"hi"     -> None
Some("a//")
"a"

See also

str::strip_suffix in the standard library ↗

Po polsku

Lustrzane odbicie strip_prefix, tylko że najciekawsze jest tu None — to nie jest porażka, to odpowiedź. line.strip_suffix('\n') mówi wprost, czy wiersz był w ogóle zakończony ("done\n" daje Some("done"), samo "done" daje None), a trim_end tego nie powie nigdy, bo po cichu obetnie i nic nie zaraportuje — różnica robi się istotna, gdy urwany ostatni wiersz ma być błędem, a nie drobiazgiem formatowania. Obowiązuje ta sama zasada „raz, a nie wielokrotnie”: "a///".strip_suffix('/') zwraca Some("a//"), a trim_end_matches('/') zetnie wszystkie ukośniki do "a". Do obcinania rozszerzeń plików lepiej jednak użyć Path — porównanie bajtów nie wie nic o .tar.gz ani o systemach plików nierozróżniających wielkości liter.

Szukaj po polsku: usuwanie przyrostka · zakończenie wiersza · rust strip_suffix vs trim_end · rust strip file extension Path