std.strings

Byte-string search, transformation, splitting, and parsing.

Importuse std.strings

Functions

fn to_upper(text: string) -> string#

Converts ASCII letters to uppercase.

  • text: Text to convert; bytes outside a-z are copied unchanged.
println("moon".to_upper()) // MOON
println("MOON".to_lower()) // moon
fn to_lower(text: string) -> string#

Converts ASCII letters to lowercase.

  • text: Text to convert; bytes outside A-Z are copied unchanged.
fn slice(text: string, start: int, end: int) -> string#

Returns a clamped half-open slice.

  • text: Text to take the slice from.
  • start: First byte index, clamped into the text.
  • end: One past the last byte index, clamped to at least start.
println(std.strings.slice("moonlight", 0, 4))  // moon
println(std.strings.slice("moonlight", 4, 99)) // light
fn sub(text: string, start: int, end: int) -> string#

Returns a clamped half-open substring.

  • text: Text to take the substring from.
  • start: First byte index, clamped into the text.
  • end: One past the last byte index, clamped to at least start.
fn trim_ascii(text: string) -> string#

Trims ASCII whitespace from both ends.

  • text: Text to trim.
println("  moon  ".trim_ascii())       // moon
println("  moon  ".trim_left() + "|")  // moon  |
println("|" + "  moon  ".trim_right()) // |  moon
fn trim_left(text: string) -> string#

Trims ASCII whitespace from the left edge.

  • text: Text to trim.
fn trim_right(text: string) -> string#

Trims ASCII whitespace from the right edge.

  • text: Text to trim.
fn from_code(code: int) -> string#

Builds a one-byte string from an integer code.

  • code: Byte value, taken modulo 256.
fn ch(text: string, index: int) -> string#

Returns the one-byte string at the requested index.

  • text: Text to read from.
  • index: Byte index to read.
println(std.strings.ch("moon", 1)) // o
fn replace(text: string, old: string, replacement: string) -> string#

Replaces the first matching occurrence.

  • text: Text to rewrite.
  • old: Value to look for; when absent the text is returned unchanged.
  • replacement: Value to put in its place.
println("banana".replace("an", "AN"))     // bANana
println("banana".replace_all("an", "AN")) // bANANa
fn replace_all(text: string, old: string, replacement: string) -> string#

Replaces every matching occurrence.

  • text: Text to rewrite.
  • old: Value to look for; when absent the text is returned unchanged.
  • replacement: Value to put in place of every match.
fn join(parts: [string], separator: string) -> string#

Joins the supplied values into one result.

  • parts: Pieces to concatenate, in order.
  • separator: Value placed between consecutive pieces.
println(["2026", "08", "30"].join("-")) // 2026-08-30
fn repeat(text: string, count: int) -> string#

Repeats text the requested number of times.

  • text: Text to repeat.
  • count: How many copies to emit; zero or negative yields an empty string.
println("ab".repeat(3)) // ababab
fn reverse(text: string) -> string#

Returns the values in reverse order.

  • text: Text whose bytes are reversed.
println("moon".reverse()) // noom
fn pad_left(text: string, width: int, fill: string) -> string#

Pads the left side to the requested width.

  • text: Text to pad.
  • width: Target byte width; a shorter target returns the text unchanged.
  • fill: Padding value, repeated to close the gap; an empty fill pads nothing.
println(std.strings.pad_left("42", 5, "0"))    // 00042
println(std.strings.pad_right("moon", 6, ".")) // moon..
println(std.strings.center("moon", 9, "-"))    // --moon---
fn pad_right(text: string, width: int, fill: string) -> string#

Pads the right side to the requested width.

  • text: Text to pad.
  • width: Target byte width; a shorter target returns the text unchanged.
  • fill: Padding value, repeated to close the gap; an empty fill pads nothing.
fn center(text: string, width: int, fill: string) -> string#

Centers text within the requested width.

  • text: Text to centre.
  • width: Target byte width; a shorter target returns the text unchanged.
  • fill: Padding value; an odd remainder goes to the right side.
fn truncate(text: string, maximum: int, suffix: string) -> string#

Shortens text to the maximum width and appends a suffix.

  • text: Text to shorten.
  • maximum: Byte budget for the whole result, suffix included.
  • suffix: Marker appended when the text is actually shortened.
println(std.strings.truncate("moonlight tour", 9, "...")) // moonli...
println(std.strings.truncate("moon", 9, "..."))           // moon
fn len(text: string) -> int#

Returns the number of elements.

  • text: Text whose byte length is returned.
println("moon".len())   // 4
println("".is_empty())  // true
fn find(text: string, needle: string) -> int#

Returns the first match.

  • text: Text to search.
  • needle: Value to look for; an empty needle matches at 0.
println("banana".find("an"))     // 1
println("banana".rfind("an"))    // 3
println("banana".find("z"))      // -1
println("banana".contains("an")) // true
fn find_from(text: string, needle: string, from: int) -> int#

Returns the first match at or after the supplied byte index.

  • text: Text to search.
  • needle: Value to look for; an empty needle matches at from.
  • from: Byte index to start at; the result is -1 when no match follows it.
println(std.strings.find_from("banana", "an", 2)) // 3
fn rfind(text: string, needle: string) -> int#

Byte offset of the last occurrence of needle, or -1.

The backward twin of find, searching from the end so a match is found in one pass rather than by scanning forward and remembering. An empty needle answers the text's length, mirroring find's answer of 0 — both are the position where an empty match sits at that end.

  • text: Text to search.
  • needle: Value to look for; an empty needle matches at the text's length.
fn count(text: string, needle: string) -> int#

Counts non-overlapping occurrences.

  • text: Text to search.
  • needle: Value to count; matches are consumed left to right and never overlap.
println("banana".count("an")) // 2
fn parse_int(text: string) -> int#

Parses int.

  • text: Text to read, with an optional leading sign and no surrounding space.
println(std.strings.parse_int("-42")) // -42
println(std.strings.parse_int("4x2")) // 0
fn try_parse_int(raw: string) -> Result<int, Error>#

Attempts to parse int, returning failures as error values.

  • raw: Text to read, with an optional leading sign and no surrounding space.
match std.strings.try_parse_int("4x2") {
  ok(n) => println(n),
  err(_) => println("not a number"), // not a number
}
extern fn try_parse_float(text: string) -> Result<float, Error>#

Attempts to parse float, returning failures as error values.

  • text: Text to read in decimal or exponent notation.
fn char_code(text: string, index: int) -> int#

Returns the byte value at the requested index.

  • text: Text to read from.
  • index: Byte index to read.
fn byte_at(text: string, index: int) -> int#

Returns the byte value at the requested index.

  • text: Text to read from.
  • index: Byte index to read.
println(std.strings.byte_at("moon", 0))  // 109
println(std.strings.byte_at("moon", 99)) // -1
fn bytes(text: string) -> [int]#

Returns the string's byte values.

  • text: Text to expand into one integer per byte.
println(std.strings.bytes("moon"))                    // [109, 111, 111, 110]
println(std.strings.from_bytes([109, 111, 111, 110])) // moon
println(std.strings.from_code(33))                    // !
fn from_bytes(values: [int]) -> string#

Builds a string from integer byte values.

  • values: Byte values, each taken modulo 256.
extern fn parse_float(text: string) -> float#

Parses float.

  • text: Text to read in decimal or exponent notation.
println(std.strings.parse_float("2.5"))    // 2.5
println(std.strings.parse_float("3.25e2")) // 325
fn starts_with(text: string, prefix: string) -> bool#

Reports whether text begins with the prefix.

  • text: Text to examine.
  • prefix: Prefix to test for; an empty prefix always matches.
println("moon.mn".starts_with("moon")) // true
println("moon.mn".ends_with(".mn"))    // true
fn ends_with(text: string, suffix: string) -> bool#

Reports whether text ends with the suffix.

  • text: Text to examine.
  • suffix: Suffix to test for; an empty suffix always matches.
fn contains(text: string, needle: string) -> bool#

Reports whether the requested value is present.

  • text: Text to search.
  • needle: Value to look for; an empty needle is always present.
fn is_alpha(text: string) -> bool#

Reports whether every byte is an ASCII letter.

  • text: Text to examine.
println("moon".is_alpha())   // true
println("moon42".is_alpha()) // false
println("moon42".is_alnum()) // true
println("42".is_digit())     // true
fn is_digit(text: string) -> bool#

Reports whether every byte is an ASCII digit.

  • text: Text to examine.
fn is_alnum(text: string) -> bool#

Reports whether every byte is an ASCII letter or digit.

  • text: Text to examine.
fn is_space(text: string) -> bool#

Reports whether every byte is ASCII whitespace.

  • text: Text to examine.
fn is_upper(text: string) -> bool#

Reports whether every byte is uppercase ASCII.

  • text: Text to examine.
fn is_lower(text: string) -> bool#

Reports whether every byte is lowercase ASCII.

  • text: Text to examine.
fn is_empty(text: string) -> bool#

Reports whether empty.

  • text: Text to examine.
fn split(text: string, delimiter: string) -> [string]#

Splits the input at the requested separators.

  • text: Text to divide.
  • delimiter: Separator to cut at; an empty delimiter yields the whole text as one piece.
println("a,b,,c".split(",")) // ["a", "b", "", "c"]
fn chars(text: string) -> [string]#

Splits text into character strings.

  • text: Text to divide into one-byte strings.
println("moon".chars()) // ["m", "o", "o", "n"]
fn lines(text: string) -> [string]#

Splits text into lines.

  • text: Text to divide at newlines; a trailing "\r" is dropped from each line and a trailing newline does not yield a final empty line.
println(std.strings.lines("one\ntwo\r\nthree\n")) // ["one", "two", "three"]
fn words(text: string) -> [string]#

Splits text into ASCII-whitespace-delimited words.

  • text: Text to divide; runs of whitespace collapse and empty words are dropped.
println(std.strings.words(" the  moon  tour ")) // ["the", "moon", "tour"]