2026-01-26 04:12:14 +00:00
{# retoor < retoor @ molodetz . nl > #}
{% extends 'page.html' %}
2026-01-25 03:58:39 +00:00
2026-01-26 04:12:14 +00:00
{% set page_title = "String" %}
{% set breadcrumb = [{"url": "api/index.html", "title": "API Reference"}, {"title": "String"}] %}
{% set prev_page = {"url": "api/index.html", "title": "Overview"} %}
{% set next_page = {"url": "api/http.html", "title": "http"} %}
{% block article %}
2026-01-25 03:58:39 +00:00
< h1 > String</ h1 >
< p > The < code > String</ code > class is a core type available globally without imports. Strings in Wren are immutable sequences of bytes, typically representing UTF-8 encoded text. All methods return new strings rather than modifying the original.</ p >
< pre >< code > var s = "Hello World"
System.print(s.lower) // hello world
System.print(s.upper) // HELLO WORLD
System.print(s.title) // Hello World
System.print(s.reverse) // dlroW olleH</ code ></ pre >
< h2 > Case Conversion</ h2 >
< div class = "method-signature" >
< span class = "method-name" > lower</ span > → < span class = "type" > String</ span >
</ div >
< p > Returns the string with all ASCII uppercase characters converted to lowercase.</ p >
< pre >< code > "Hello World".lower // "hello world"
"ABC 123".lower // "abc 123"</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > upper</ span > → < span class = "type" > String</ span >
</ div >
< p > Returns the string with all ASCII lowercase characters converted to uppercase.</ p >
< pre >< code > "Hello World".upper // "HELLO WORLD"
"abc 123".upper // "ABC 123"</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > capitalize</ span > → < span class = "type" > String</ span >
</ div >
< p > Returns the string with the first character uppercased and the rest lowercased.</ p >
< pre >< code > "hello world".capitalize // "Hello world"
"HELLO".capitalize // "Hello"</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > title</ span > → < span class = "type" > String</ span >
</ div >
< p > Returns the string with the first character of each word capitalized and the rest lowercased. Words are separated by whitespace.</ p >
< pre >< code > "hello world".title // "Hello World"
"HELLO WORLD".title // "Hello World"</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > swapCase</ span > → < span class = "type" > String</ span >
</ div >
< p > Returns the string with uppercase characters converted to lowercase and vice versa.</ p >
< pre >< code > "Hello World".swapCase // "hELLO wORLD"</ code ></ pre >
< h2 > Character Testing</ h2 >
< div class = "method-signature" >
< span class = "method-name" > isLower</ span > → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if the string contains at least one alphabetic character and all alphabetic characters are lowercase.</ p >
< pre >< code > "hello".isLower // true
"hello1".isLower // true
"Hello".isLower // false
"123".isLower // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > isUpper</ span > → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if the string contains at least one alphabetic character and all alphabetic characters are uppercase.</ p >
< pre >< code > "HELLO".isUpper // true
"HELLO1".isUpper // true
"Hello".isUpper // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > isDigit</ span > → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if the string is non-empty and all bytes are ASCII digits (0-9).</ p >
< pre >< code > "12345".isDigit // true
"123a5".isDigit // false
"".isDigit // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > isAlpha</ span > → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if the string is non-empty and all bytes are ASCII letters (a-z, A-Z).</ p >
< pre >< code > "hello".isAlpha // true
"hello1".isAlpha // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > isAlphaNumeric</ span > → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if the string is non-empty and all bytes are ASCII letters or digits.</ p >
< pre >< code > "hello123".isAlphaNumeric // true
"hello!".isAlphaNumeric // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > isSpace</ span > → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if the string is non-empty and all bytes are ASCII whitespace (space, tab, newline, carriage return, form feed, vertical tab).</ p >
< pre >< code > " ".isSpace // true
" \t\n".isSpace // true
"hello".isSpace // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > isAscii</ span > → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if all bytes in the string are less than 128. Returns < code > true</ code > for empty strings.</ p >
< pre >< code > "hello".isAscii // true
"".isAscii // true</ code ></ pre >
< h2 > Search</ h2 >
< div class = "method-signature" >
< span class = "method-name" > lastIndexOf</ span > (< span class = "param" > search</ span > ) → < span class = "type" > Num</ span >
</ div >
< p > Returns the byte index of the last occurrence of < code > search</ code > in the string, or < code > -1</ code > if not found.</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > search</ span > < span class = "param-type" > (String)</ span > - The substring to search for</ li >
< li >< span class = "returns" > Returns:</ span > Byte index or -1</ li >
</ ul >
< pre >< code > "hello world hello".lastIndexOf("hello") // 12
"hello".lastIndexOf("x") // -1</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > lastIndexOf</ span > (< span class = "param" > search</ span > , < span class = "param" > start</ span > ) → < span class = "type" > Num</ span >
</ div >
< p > Returns the byte index of the last occurrence of < code > search</ code > at or before < code > start</ code > , or < code > -1</ code > if not found.</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > search</ span > < span class = "param-type" > (String)</ span > - The substring to search for</ li >
< li >< span class = "param-name" > start</ span > < span class = "param-type" > (Num)</ span > - Maximum byte index to search from</ li >
< li >< span class = "returns" > Returns:</ span > Byte index or -1</ li >
</ ul >
< pre >< code > "hello world hello".lastIndexOf("hello", 11) // 0
"hello world hello".lastIndexOf("hello", 12) // 12</ code ></ pre >
< h2 > Transformation</ h2 >
< div class = "method-signature" >
< span class = "method-name" > reverse</ span > → < span class = "type" > String</ span >
</ div >
< p > Returns the string with characters in reverse order. Code point aware for UTF-8 strings.</ p >
< pre >< code > "hello".reverse // "olleh"
"abcde".reverse // "edcba"</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > center</ span > (< span class = "param" > width</ span > ) → < span class = "type" > String</ span >
</ div >
< p > Centers the string in a field of < code > width</ code > characters, padded with spaces.</ p >
< pre >< code > "hi".center(10) // " hi "</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > center</ span > (< span class = "param" > width</ span > , < span class = "param" > char</ span > ) → < span class = "type" > String</ span >
</ div >
< p > Centers the string in a field of < code > width</ code > characters, padded with the given fill character.</ p >
< pre >< code > "hi".center(10, "-") // "----hi----"</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > lpad</ span > (< span class = "param" > width</ span > , < span class = "param" > char</ span > ) → < span class = "type" > String</ span >
</ div >
< p > Left-pads the string to < code > width</ code > characters using the given fill character.</ p >
< pre >< code > "42".lpad(5, "0") // "00042"</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > rpad</ span > (< span class = "param" > width</ span > , < span class = "param" > char</ span > ) → < span class = "type" > String</ span >
</ div >
< p > Right-pads the string to < code > width</ code > characters using the given fill character.</ p >
< pre >< code > "hi".rpad(5, ".") // "hi..."</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > zfill</ span > (< span class = "param" > width</ span > ) → < span class = "type" > String</ span >
</ div >
< p > Pads the string with leading zeros to < code > width</ code > characters. Preserves a leading < code > -</ code > or < code > +</ code > sign.</ p >
< pre >< code > "42".zfill(5) // "00042"
"-42".zfill(6) // "-00042"
"+42".zfill(6) // "+00042"</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > removePrefix</ span > (< span class = "param" > prefix</ span > ) → < span class = "type" > String</ span >
</ div >
< p > If the string starts with < code > prefix</ code > , returns the string with the prefix removed. Otherwise returns the original string.</ p >
< pre >< code > "HelloWorld".removePrefix("Hello") // "World"
"HelloWorld".removePrefix("World") // "HelloWorld"</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > removeSuffix</ span > (< span class = "param" > suffix</ span > ) → < span class = "type" > String</ span >
</ div >
< p > If the string ends with < code > suffix</ code > , returns the string with the suffix removed. Otherwise returns the original string.</ p >
< pre >< code > "HelloWorld".removeSuffix("World") // "Hello"
"HelloWorld".removeSuffix("Hello") // "HelloWorld"</ code ></ pre >
< h2 > Splitting & Conversion</ h2 >
< div class = "method-signature" >
< span class = "method-name" > splitLines</ span > → < span class = "type" > List</ span >
</ div >
< p > Splits the string by line endings (< code > \n</ code > , < code > \r\n</ code > , < code > \r</ code > ) and returns a list of strings.</ p >
< pre >< code > "line1\nline2\nline3".splitLines // ["line1", "line2", "line3"]
"a\r\nb\r\nc".splitLines // ["a", "b", "c"]</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > chars</ span > → < span class = "type" > List</ span >
</ div >
< p > Returns a list of individual characters (code points) in the string.</ p >
< pre >< code > "abc".chars // ["a", "b", "c"]
"".chars // []</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > toNum</ span > → < span class = "type" > Num</ span > | < span class = "type" > Null</ span >
</ div >
< p > Parses the string as a number. Returns < code > null</ code > if the string cannot be parsed.</ p >
< pre >< code > "42".toNum // 42
"3.14".toNum // 3.14
"-7".toNum // -7
"abc".toNum // null</ code ></ pre >
< h2 > Comparison</ h2 >
< p > Strings support lexicographic comparison using the standard comparison operators. Comparison is byte-by-byte using the raw byte values, which produces correct results for ASCII and UTF-8 encoded text.</ p >
< div class = "method-signature" >
< span class = "method-name" > < </ span > (< span class = "param" > other</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if this string is lexicographically less than < code > other</ code > .</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > other</ span > < span class = "param-type" > (String)</ span > - The string to compare against</ li >
</ ul >
< pre >< code > "apple" < "banana" // true
"abc" < "abd" // true
"abc" < "abcd" // true (prefix is less than longer string)</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > > </ span > (< span class = "param" > other</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if this string is lexicographically greater than < code > other</ code > .</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > other</ span > < span class = "param-type" > (String)</ span > - The string to compare against</ li >
</ ul >
< pre >< code > "banana" > "apple" // true
"abd" > "abc" // true
"abcd" > "abc" // true</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > < =</ span > (< span class = "param" > other</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if this string is lexicographically less than or equal to < code > other</ code > .</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > other</ span > < span class = "param-type" > (String)</ span > - The string to compare against</ li >
</ ul >
< pre >< code > "abc" < = "abc" // true
"abc" < = "abd" // true
"abd" < = "abc" // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > > =</ span > (< span class = "param" > other</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Returns < code > true</ code > if this string is lexicographically greater than or equal to < code > other</ code > .</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > other</ span > < span class = "param-type" > (String)</ span > - The string to compare against</ li >
</ ul >
< pre >< code > "abc" >= "abc" // true
"abd" >= "abc" // true
"abc" >= "abd" // false</ code ></ pre >
< div class = "admonition tip" >
< div class = "admonition-title" > Tip</ div >
< p > String comparison is byte-based, so uppercase letters sort before lowercase letters in ASCII order (e.g., < code > "Z" < "a"</ code > is < code > true</ code > ). If you need case-insensitive comparison, convert both strings to the same case first using < code > lower</ code > or < code > upper</ code > .</ p >
</ div >
< h2 > Existing Methods</ h2 >
< p > The following methods are also available on all strings as part of the core VM.</ p >
< table >
< tr >
< th > Method</ th >
< th > Description</ th >
</ tr >
< tr >
< td >< code > contains(s)</ code ></ td >
< td > Returns true if the string contains < code > s</ code ></ td >
</ tr >
< tr >
< td >< code > startsWith(s)</ code ></ td >
< td > Returns true if the string starts with < code > s</ code ></ td >
</ tr >
< tr >
< td >< code > endsWith(s)</ code ></ td >
< td > Returns true if the string ends with < code > s</ code ></ td >
</ tr >
< tr >
< td >< code > indexOf(s)</ code ></ td >
< td > Returns the byte index of < code > s</ code > , or -1</ td >
</ tr >
< tr >
< td >< code > indexOf(s, start)</ code ></ td >
< td > Returns the byte index of < code > s</ code > starting from < code > start</ code ></ td >
</ tr >
< tr >
< td >< code > split(delim)</ code ></ td >
< td > Splits by delimiter, returns a list</ td >
</ tr >
< tr >
< td >< code > replace(from, to)</ code ></ td >
< td > Replaces all occurrences of < code > from</ code > with < code > to</ code ></ td >
</ tr >
< tr >
< td >< code > trim()</ code ></ td >
< td > Removes leading and trailing whitespace</ td >
</ tr >
< tr >
< td >< code > trimStart()</ code ></ td >
< td > Removes leading whitespace</ td >
</ tr >
< tr >
< td >< code > trimEnd()</ code ></ td >
< td > Removes trailing whitespace</ td >
</ tr >
< tr >
< td >< code > bytes</ code ></ td >
< td > Returns a sequence of byte values</ td >
</ tr >
< tr >
< td >< code > codePoints</ code ></ td >
< td > Returns a sequence of code point values</ td >
</ tr >
< tr >
< td >< code > count</ code ></ td >
< td > Number of code points in the string</ td >
</ tr >
< tr >
< td >< code > isEmpty</ code ></ td >
< td > Returns true if the string has no characters</ td >
</ tr >
< tr >
< td >< code > *(n)</ code ></ td >
< td > Repeats the string < code > n</ code > times</ td >
</ tr >
</ table >
< div class = "admonition note" >
< div class = "admonition-title" > Note</ div >
< p > String is a core type available globally. No < code > import</ code > statement is needed. All string methods operate on ASCII characters. Multi-byte UTF-8 characters are preserved but case conversion applies only to ASCII letters (a-z, A-Z).</ p >
</ div >
2026-01-26 04:12:14 +00:00
{% endblock %}