Skip to content

str::strip_circumfix

str methods · Strings

Level: reference · for working programmers

One line: Removes a prefix and a suffix in one call, returning Some(middle) only if both were present.

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

Stable since 1.98.0.

The all-or-nothing rule is the point. s.strip_prefix('"').and_then(|s| s.strip_suffix('"')) expresses the same thing in two steps; this is one call that cannot be half-written.

Unquoting is the obvious use, and brackets, and any wrapper that must be balanced: <...>, {{...}}, /*...*/.

The prefix and suffix must not overlap. On a string shorter than both together, the result is None rather than a piece of text counted twice — so "\"".strip_circumfix('"', '"') is None, where the two-step chain would also give None but only because the second step found nothing left. Same answer, arrived at honestly.

Stabilized recently, so check your MSRV before using it in a published crate; the two-step chain is the portable spelling.

Example

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

fn main() {
    println!("{:?}", "\"hello\"".strip_circumfix('"', '"'));
    println!("{:?}", "<tag>".strip_circumfix('<', '>'));
    println!("{:?}", "/* note */".strip_circumfix("/*", "*/"));

    // Both, or nothing.
    for q in ["\"hi\"", "\"hi", "hi\"", "hi"] {
        println!("{:<8} -> {:?}", format!("{q:?}"), q.strip_circumfix('"', '"'));
    }

    // No double-counting when the string is too short to hold both.
    println!("{:?}", "\"".strip_circumfix('"', '"'));
    println!("{:?}", "".strip_circumfix('"', '"'));

    // The portable two-step spelling.
    let q = "\"hi\"";
    println!("{:?}", q.strip_prefix('"').and_then(|s| s.strip_suffix('"')));
}

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

Some("hello")
Some("tag")
Some(" note ")
"\"hi\"" -> Some("hi")
"\"hi"   -> None
"hi\""   -> None
"hi"     -> None
None
None
Some("hi")

See also

str::strip_circumfix in the standard library ↗

Po polsku

strip_circumfix zdejmuje prefiks i sufiks za jednym zamachem i zwraca Some(środek) wyłącznie wtedy, gdy oba rzeczywiście były na miejscu — zasada „wszystko albo nic” jest tu całą treścią metody. Dla polskiego tekstu wypada to lepiej, niż mogłoby się wydawać, bo nasze cudzysłowy są asymetryczne: "„cześć”".strip_circumfix('„', '”') daje Some("cześć"), a trim_matches w tym miejscu obcinałby powtarzające się znaki i w ogóle nie pilnował, czy otwarcie ma swoje zamknięcie. Krótkiego tekstu ta metoda też nie da się oszukać — prefiks i sufiks nie mogą na siebie zachodzić, więc sam " daje None, a nie kawałek policzony dwa razy. Stabilne jest to dopiero od 1.98.0, więc w publikowanym crate sprawdź najpierw MSRV; przenośny zapis tego samego to strip_prefix(..).and_then(|s| s.strip_suffix(..)).

Szukaj po polsku: polskie cudzysłowy w kodzie · zdejmowanie cudzysłowów z tekstu · rust strip_circumfix · rust strip_prefix and_then strip_suffix