Skip to content

str::strip_prefix

str methods · Strings

Level: reference · for working programmers

One line: Removes the prefix once and returns Some(rest), or None if it was not there — test and remove in a single step.

pub fn strip_prefix<P: Pattern>(&self, prefix: P) -> Option<&str>

Stable since 1.45.0.

The Option is what makes this better than starts_with plus a slice. The alternative spelling has to repeat the prefix's length by hand:

fn main() {
    let flag = "--verbose";
    if flag.starts_with("--") { println!("{}", &flag[2..]); }   // the 2 must match "--"
    if let Some(n) = flag.strip_prefix("--") { println!("{n}"); } // nothing to get wrong
}

That hand-written offset is where multi-byte prefixes break: "é".len() is 2, so &s[1..] panics.

Once, not repeatedly — that is the whole difference from trim_start_matches. Stripping one ../ is this; removing every leading ../ is that.

Command-line flag parsing is the canonical use, and the Option chains: .strip_prefix("--").or_else(|| s.strip_prefix('-')) tries long form then short.

Example

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

fn main() {
    println!("{:?}", "--verbose".strip_prefix("--"));
    println!("{:?}", "plain".strip_prefix("--"));

    // Once, not repeatedly.
    println!("{:?}", "../../src".strip_prefix("../"));
    println!("{:?}", "../../src".trim_start_matches("../"));

    // No byte arithmetic, so a multi-byte prefix is safe.
    println!("{:?}", "→next".strip_prefix('→'));

    // Flag parsing: long form, then short.
    for arg in ["--verbose", "-v", "file.txt"] {
        let parsed = arg.strip_prefix("--").map(|n| format!("long {n}"))
            .or_else(|| arg.strip_prefix('-').map(|n| format!("short {n}")))
            .unwrap_or_else(|| format!("positional {arg}"));
        println!("{arg:<11} {parsed}");
    }
}

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

Some("verbose")
None
Some("../src")
"src"
Some("next")
--verbose   long verbose
-v          short v
file.txt    positional file.txt

See also

str::strip_prefix in the standard library ↗

Po polsku

strip_prefix skleja dwie czynności w jedną: sprawdza, czy przedrostek w ogóle występuje, i od razu oddaje resztę jako Some(reszta) — albo None, gdy przedrostka nie było, więc test i obcięcie nigdy nie rozjadą się ze sobą. Polski czytelnik ma tu jeden bardzo konkretny powód, żeby nie pisać wersji ręcznej: &flag[2..] wymaga podania długości przedrostka w bajtach, a ą, ę, ł zajmują po dwa bajty, więc wycinek łańcucha (string slice) wyliczony „na oko” kończy się paniką: indeks nie wypada na granicy znaku (char boundary). Druga rzecz to „raz, a nie wielokrotnie”: "../../src".strip_prefix("../") daje Some("../src"), podczas gdy trim_start_matches("../") zdejmie wszystkie warstwy i zostawi "src" — po strip_prefix sięgaj wtedy, gdy chcesz usunąć dokładnie jedną.

Szukaj po polsku: usuwanie przedrostka · granica znaku w łańcuchu · rust strip_prefix vs trim_start_matches · rust byte index is not a char boundary