Skip to content

str::rsplit_once

str methods · Strings

Level: reference · for working programmers

One line: Splits at the last match into exactly two pieces, or None — the tool for stem-and-extension.

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

Stable since 1.52.0.

Same shape as split_once, anchored at the other end. The tuple is in reading order — (before, after) — which is the difference from rsplitn, whose iterator yields the last field first.

"a.b.c".rsplit_once('.') is Some(("a.b", "c")).

Use it whenever the delimiter can appear more than once and it is the last one that matters: a file extension, host:port, the final path segment. For filenames specifically, Path knows the platform rules this does not.

Example

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

fn main() {
    for name in ["a.b.c", "noext", ".hidden", "trailing."] {
        println!("{:<11} -> {:?}", format!("{name:?}"), name.rsplit_once('.'));
    }

    // Reading order, unlike rsplitn.
    let path = "/usr/local/bin/rustc";
    println!("{:?}", path.rsplit_once('/'));
    println!("{:?}", path.rsplitn(2, '/').collect::<Vec<&str>>());

    // host:port, where the host may itself contain colons.
    for addr in ["example.com:8080", "::1:9000"] {
        println!("{:<18} -> {:?}", format!("{addr:?}"), addr.rsplit_once(':'));
    }
}

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

"a.b.c"     -> Some(("a.b", "c"))
"noext"     -> None
".hidden"   -> Some(("", "hidden"))
"trailing." -> Some(("trailing", ""))
Some(("/usr/local/bin", "rustc"))
["rustc", "/usr/local/bin"]
"example.com:8080" -> Some(("example.com", "8080"))
"::1:9000"         -> Some(("::1", "9000"))

See also

str::rsplit_once in the standard library ↗

Po polsku

Przedrostek r w rsplit_once (od reverse) odwraca wyłącznie kierunek szukania separatora — nie kolejność tego, co dostajesz. Krotka zawsze wraca w kolejności czytania, (przed, po), więc "a.b.c".rsplit_once('.') to Some(("a.b", "c")); to właśnie różni tę metodę od rsplitn, której iterator wypluwa najpierw ostatnie pole. Drugi szczegół, dla którego w ogóle warto sięgać po Option zamiast po rfind: brak separatora to None, a separator na samym początku to Some(("", "hidden")) — „nie ma kropki” i „lewa strona jest pusta” są tu rozróżnialne, czego zwykłe szukanie indeksu nie daje. Do nazw plików i tak lepszy jest Path, który zna reguły systemu plików, nieznane gołemu wycinkowi łańcucha (string slice).

Szukaj po polsku: dzielenie łańcucha od końca · ostatnie wystąpienie separatora · rozdzielanie nazwy i rozszerzenia · rust rsplit_once · rust split string at last occurrence