Docs/Language basics

Strings

Build, search, slice and format text.

On this page

A String is read-only text, normally UTF-8. Methods that change text, such as upper() or replace(), return a new string.

Write a string#

Valk
fn main() {
    let name = "Ada"
    println("Hello " + name + "!")         // concatenation
    println("Hello %name!")                // insert a variable
    println("Twice: %{name.length * 2}")   // insert an expression
    println("Cost: \%5")                   // a literal %
    println(r"Raw: %name\n")               // raw string, no escapes
    println("Tab:\tquote:\" slash:\\")
}

A string literal may span several lines. Any value that converts to a String can go inside %{ }, numbers included.

Inspect text#

Valk
fn main() {
    let text = "Hello, World"
    println(text.length)                // 12 (bytes)
    println(text.starts_with("Hello"))  // true
    println(text.contains("World"))     // true
    println(text.index_of("World") !? 0) // 7
    println(text.count("l"))            // 3
    println(text.is_empty())            // false
    println(text == "Hello, World")     // true
}
Method Returns
length Number of bytes
starts_with(s), ends_with(s), contains(s) bool
index_of(s), last_index_of(s) Byte offset; throws when not found
count(s) How often s occurs
is_empty() bool
is_integer(), is_number(), is_alpha(), is_alpha_numeric() bool
equals_ignore_ascii_case(s) bool

Strings compare with == and sort with < and > in byte order.

Change text#

Valk
fn main() {
    let text = "  Hello, World  ".trim()
    println(text.upper())                     // HELLO, WORLD
    println(text.replace("World", "Valk"))    // Hello, Valk
    println("--a--".trim("-"))                // a
    println("ab".repeat(3))                   // ababab
    println("7".pad_left('0', 3))             // 007
}
Method Result
trim(), ltrim(), rtrim() Without whitespace, or without a given part
lower(), upper() Unicode case mapping
replace(part, with) Every occurrence replaced
repeat(n) n copies
pad_left(char, length), pad_right(char, length) Padded to length bytes
escape(), unescape() Backslash escapes added or removed

Split and join#

Valk
fn main() {
    let parts = "red,green,blue".split(",")
    println(parts.length)                     // 3
    println("a=b=c".split("=", 2).join(" | "))  // a | b=c
    each "one  two three".words() as word {
        print("[%word]")                      // [one][two][three]
    }
    println("")
    each "first\nsecond".lines() as line : println(line)
}

split(on, limit) keeps empty parts; a limit returns at most that many parts. words() splits at whitespace and skips empty parts. join on an array puts a divider between items.

Take part of a string#

Valk
fn main() {
    let text = "Hello, World"
    println(text.range(0, 5))   // Hello
    println(text[7 .. 5])       // World
    println(text[0])            // 72
    println(text[0] == 'H')     // true
    each "abc" as byte : print(byte.to(String) + " ") // 97 98 99
    println("")
}

A range is a start and a length, in bytes: text[7 .. 5] is five bytes starting at offset 7. text[i] is one byte (u8), and each over a string visits its bytes.

Unicode characters#

Byte offsets cut through multi-byte characters. The utf8 group counts characters instead:

Valk
fn main() {
    let text = "héllo"
    println(text.length)            // 6 bytes
    println(text.utf8.length)       // 5 characters
    println(text.utf8.range(1, 2))  // él
    println(text.utf8.get(1))       // é
    each text.utf8.chars() as ch : print(ch + " ") // h é l l o
    println("")
}

Each character is returned as a String. A visible character, such as an emoji with a skin tone, can consist of several code points.

Build long text#

Repeated + copies the text each time. For text built in a loop, write into a ByteBuffer:

Valk
fn main() {
    let out = ByteBuffer.new()
    each 1 .. 3 as i {
        out.write("line %i\n")
    }
    out.write_byte('!')
    print(out.to_string())  // line 1, line 2, line 3, !
    println("")
}

To build a string from a list, collect the parts in an Array[String] and call join.

Format numbers#

Code Result
"%n" Shortest form: 3.5, 3, 42
x.to_string(2) Two decimals: 3.14
n.to(String).pad_left('0', 4) Zero-padded: 0042

See Variables & types for turning text into numbers, Regular expressions for pattern matching, and Terminal output for colors.