str methods¶
Level: reference · for working programmers
One line: One page per method on the str primitive — all 83 that stable Rust 1.98 exposes — each with the signature, what it actually does, the trap it is usually involved in, and a program whose printed output is checked by CI.
These pages are a reference, not a course. If you have not met String and &str yet, read the strings arc first — it explains the owner-and-view pattern that makes half of this list make sense. Come back here when you know which method you want and need to know how it behaves at the edges.
Every page has the same shape: a one-line summary, the signature, the stability line, the prose, then a complete runnable program and its verified output. Nothing on any of these pages is hand-typed output — tools/run_examples.py compiles each example, runs it, and fails the build if what the page shows is not what the program printed.
Where a page prints a table of inputs and results, the input column is built with format!("{s:?}") and then padded as a plain String. The obvious spelling, {s:<7?}, compiles and silently does nothing: width and alignment reach every Debug impl as Formatter state, and the one for &str never reads it — so the arrows do not line up and nothing warns you. That trap has its own section on the Debug and Display page.
The signature block is a text fence rather than a rust one on purpose: a bare pub fn … is not something you can paste into a file, and the house rule is that the first rust block on a page must compile. The first rust block here is always the real example.
The pattern argument¶
Twenty-odd methods below take a P: Pattern, and that one trait is why searching, splitting, trimming and replacing all accept the same four shapes:
| shape | example | matches | worked example |
|---|---|---|---|
char |
s.split(',') |
that one character | split |
&str |
s.split(", ") |
that exact substring | split_once |
&[char] |
s.split(&['-', '_'][..]) |
any one of those characters | trim_matches |
FnMut(char) -> bool |
s.split(char::is_numeric) |
any character the closure approves | matches |
The last column is a page whose program uses that shape and is compiled and run by CI, so you can read the row working rather than take it on trust — and the four pages are four different methods, which is the trait's whole point. For all four shapes in one program, contains calls it four times, one line per shape.
&[char] is the shape that stays unfamiliar: of the 83 examples here only three use it — contains, split and trim_matches. The [..] on it is a habit rather than a requirement, and worth not copying into new code: Pattern is implemented for [char; N] and &[char; N] too, so s.split(['-', '_']) compiles and does the same thing.
A &str pattern is never accepted where the method has to search backwards from both ends at once — trim_matches is the one that refuses it. Chain the two one-sided methods there instead.
The two panics¶
Almost every panic in this list is one of two, and both are about byte offsets:
- out of range — the offset is past
len() - inside a character — the offset is not a character boundary, because
len()counts bytes and acharcan occupy up to four of them
is_char_boundary is the test, get and the _checked methods return Option instead of panicking, and floor_char_boundary repairs an offset rather than refusing it.
How long is it, and what is it made of¶
| method | what it does |
|---|---|
len |
The byte count — not the character count |
is_empty |
len() == 0, spelled so it reads |
as_bytes |
The UTF-8 bytes as &[u8], free |
bytes |
The same bytes as an iterator of u8 |
chars |
An iterator of char — Unicode scalars, not graphemes |
char_indices |
Characters with the byte offsets you can slice at |
lines |
Split on \n, dropping a trailing \r and the final empty line |
is_ascii |
Whether every byte is under 128 — the ascii family's precondition |
Is it there, and where¶
Every method here takes a pattern.
| method | what it does |
|---|---|
contains |
Whether the pattern occurs anywhere |
starts_with |
Whether it occurs at the front |
ends_with |
Whether it occurs at the back |
find |
The byte offset of the first match, as Option<usize> |
rfind |
The byte offset of the last match |
matches |
The matched substrings themselves |
rmatches |
The same, yielded back to front |
match_indices |
Each match with its byte offset |
rmatch_indices |
The same, back to front — the order in-place edits need |
substr_range |
Where a sub-slice sits in this string — identity, not search |
Cutting it up¶
Splits report the gaps between matches, so n matches give n+1 pieces.
| method | what it does |
|---|---|
split |
The pieces between the matches — empties included |
rsplit |
The same pieces, last to first |
splitn |
At most n pieces; the remainder stays whole |
rsplitn |
The same limit, applied from the right |
split_once |
Exactly two pieces at the first match, or None |
rsplit_once |
Exactly two pieces at the last match, or None |
split_terminator |
Drops a trailing empty piece |
rsplit_terminator |
The same rule, iterated from the right |
split_inclusive |
Keeps the separator on the piece it ended |
split_whitespace |
Collapses runs of whitespace — the editorial split, for prose |
split_ascii_whitespace |
The same, ASCII-only and faster |
split_at |
Two halves at a byte offset — panics off a boundary |
split_at_checked |
The same cut, returning Option |
split_at_mut |
Two mutable halves, which plain borrowing cannot give |
split_at_mut_checked |
The mutable cut, returning Option |
Taking things off the ends¶
| method | what it does |
|---|---|
trim |
Unicode whitespace off both ends, borrowed |
trim_start |
The front only |
trim_end |
The back only — what to call on a line you just read |
trim_matches |
A pattern off both ends, repeatedly |
trim_start_matches |
Repeatedly, at the front — accepts a &str |
trim_end_matches |
Repeatedly, at the back |
trim_ascii |
ASCII whitespace only, and const |
trim_ascii_start |
The front only, const |
trim_ascii_end |
The back only, const |
strip_prefix |
Removes it once and tells you whether it was there |
strip_suffix |
The same at the back |
strip_circumfix |
Both ends at once — Some only if both matched |
Changing the case¶
The ascii half is length-preserving; the Unicode half is not.
| method | what it does |
|---|---|
to_lowercase |
Full Unicode — context-sensitive, and can change length |
to_uppercase |
Full Unicode — ß becomes SS, so it does not round-trip |
to_ascii_lowercase |
A–Z only, everything else untouched |
to_ascii_uppercase |
a–z only — no ß expansion |
make_ascii_lowercase |
The same, in place, no allocation |
make_ascii_uppercase |
The same, in place |
eq_ignore_ascii_case |
Case-insensitive comparison with no allocation at all |
Making a new string out of this one¶
Everything here allocates — a str cannot change its own length.
| method | what it does |
|---|---|
replace |
Every occurrence of a pattern |
replacen |
The first n occurrences |
repeat |
n copies, allocated once |
parse |
Into any FromStr type — and it does not trim first |
into_string |
Box<str> → String, without copying |
into_boxed_bytes |
Box<str> → Box<[u8]>, without copying |
Byte offsets, and the panics they cause¶
The two failure modes are always the same: out of range, or inside a character.
| method | what it does |
|---|---|
get |
Slicing that returns Option instead of panicking |
get_mut |
The same, mutable |
is_char_boundary |
Whether an offset is a legal slice endpoint |
floor_char_boundary |
Nudge a bad offset down — the safe byte-budget truncation |
ceil_char_boundary |
Nudge it up — can exceed the budget, and panics past the end |
Bytes in, bytes out¶
| method | what it does |
|---|---|
from_utf8 |
Validate &[u8] into &str, borrowing |
from_utf8_mut |
The same, mutable |
encode_utf16 |
Out to UTF-16 code units — surrogate pairs make a third length |
escape_debug |
As {:?} prints it — printable non-ASCII stays readable |
escape_default |
Escaped to pure ASCII |
escape_unicode |
Every character as \u{...}, no exceptions |
as_ptr |
The raw address — for FFI, and not NUL-terminated |
as_mut_ptr |
The writable raw address |
unsafe — the checks removed¶
Each one trades a cheap check for an obligation you now carry.
| method | what it does |
|---|---|
as_bytes_mut |
Writable bytes — must still be valid UTF-8 when the borrow ends |
get_unchecked |
get with no bounds or boundary check |
get_unchecked_mut |
The mutable version |
from_utf8_unchecked |
&[u8] → &str with no validation |
from_utf8_unchecked_mut |
The mutable version — unvalidated and writable |
Deprecated, and still compiling¶
Here because you will meet them in older code.
| method | what it does |
|---|---|
trim_left |
→ trim_start |
trim_right |
→ trim_end |
trim_left_matches |
→ trim_start_matches |
trim_right_matches |
→ trim_end_matches |
lines_any |
→ lines |
slice_unchecked |
→ get_unchecked |
slice_mut_unchecked |
→ get_unchecked_mut |
Where to go next¶
Stringmethods — the owning half of the pair, 42 more pages- The strings arc — the lessons these pages are a reference for
strin the standard library ↗ — the official documentation these pages explain
Po polsku¶
Ta strona jest spisem, a nie lekcją: 83 metody prymitywu str, każda na własnej stronie, z sygnaturą, pułapką i programem, który CI kompiluje i uruchamia. Jeśli podział na String (właściciel, łańcuch znaków na stercie) i &str (wycinek łańcucha, sam podgląd) jeszcze się nie ułożył, zacznij od strony o łańcuchach znaków — połowa tej listy robi się zrozumiała dopiero wtedy.
Argument nazywany tu wzorcem (P: Pattern) potrafi zmylić, bo to nie jest wyrażenie regularne — biblioteka standardowa Rusta nie ma regexów w ogóle, od tego jest crate regex. Pattern przyjmuje cztery kształty: pojedynczy char, dosłowny podłańcuch &str, tablicę &[char] (pasuje którykolwiek z wymienionych znaków) i domknięcie FnMut(char) -> bool. Dlatego split, find, trim_matches i replace biorą dokładnie to samo, i dlatego jedna nauczona rzecz obsługuje dwadzieścia metod.
Reszta strony to dwie pułapki i obie uderzają w polskiego czytelnika mocniej niż w anglojęzycznego, bo nasz tekst nie jest ASCII. Pierwsza: wszystkie przesunięcia są bajtowe. "żółw".len() to 7, a nie 4 — ż, ó i ł zajmują w UTF-8 po dwa bajty — więc &s[0..1] nie zwróci „ż”, tylko spanikuje komunikatem end byte index 1 is not a char boundary; it is inside 'ż' (bytes 0..2 of string). Liczbę znaków daje chars().count(), pozycję do cięcia char_indices, a is_char_boundary, get i floor_char_boundary to trzy sposoby na to, żeby zamiast paniki dostać odpowiedź.
Druga: mnóstwo metod z powyższych tabel ma bliźniaka z ascii w nazwie i dla polskiego tekstu ta wersja bywa cicho zła — nie wywala się, po prostu nic nie robi:
to_ascii_uppercasezostawia"żółw"bez zmian; wielkie litery daje dopieroto_uppercase→"ŻÓŁW"eq_ignore_ascii_caseuzna"Łódź"i"łódź"za różne łańcuchytrim_asciiisplit_ascii_whitespacenie widzą twardej spacji U+00A0, którą polska typografia stawia po jednoliterowych wyrazach „w”, „z”, „i”, „a”
Wersje bez ascii są wolniejsze i czasem alokują, ale to one rozumieją polski. Po ascii sięgaj świadomie — do nagłówków HTTP, protokołów, identyfikatorów — a nie do tekstu, który ktoś napisał.
Szukaj po polsku: metody łańcuchów znaków · przesunięcie bajtowe a znak · rust str methods · rust Pattern trait split · rust not a char boundary