StringImmutable UTF-8 text -- the type of 'single-quoted' literals (a double quote starts a comment in Quoin, so strings are single-quoted). Position-based operations (length, index:, insert:at:) count characters, not bytes. Strings concatenate with +, format with %, and interpolate with .mod; every operation returns a new String.
'ab' + 'cd' "* -> abcd 'héllo'.length "* -> 5
Splitting and padding conveniences over the native String primitives.
Decoding (and base64-encoding) conveniences for Strings holding encoded data.
The type's default value: the empty string.
Interpolation: evaluate each %{...} in the receiver as a Quoin expression in the caller's scope and splice in the result's .s rendering. A malformed expression raises a catchable ParseError.
%'x = %{1 + 2}' "* -> x = 3
printf-style formatting: template % args. A List argument fills %1, %2, ... (1-based) and bare % placeholders in order; a Map argument fills named %<key> placeholders; any other value serves as a single positional argument. Substituted values are rendered with .s.
'%1-%2' % #(42 43) "* -> 42-43 '%a, %b' % #{ 'a':1 'b':2 } "* -> 1, 2 'total: %' % 7 "* -> total: 7
Concatenation (a + b). A String argument is appended directly; any other value is first rendered with .s, so 'n = ' + 5 just works.
'ab' + 'cd' "* -> abcd 'n = ' + 5 "* -> n = 5
Lexicographic less-than against another String. The one native comparison -- >, <= and >= derive from it.
'abc' < 'abd' "* -> true
Whether the argument is a character-for-character equal String; any non-String value is simply unequal, never an error.
'abc' == 'abc' "* -> true
A copy with each [ doubled, so the text is safe to embed literally in an #ANSI'…' color template (where […] opens a styled span).
'[red]cost'.ansiEscaped "* -> [[red]cost
The string's UTF-8 bytes as a Bytes. Never fails; the inverse, Bytes.asString, can (not all byte sequences are valid UTF-8).
'abc'.asBytes "* -> Bytes[3] 61 62 63
Whether the String argument occurs anywhere in the receiver.
'hello'.contains?:'ell' "* -> true
Whether the receiver ends with the String argument.
'hello'.ends?:'lo' "* -> true
This String, read as base64, decoded back to Bytes.
'aGk='.fromBase64.asString "* -> hi
This String, read as hex, decoded back to Bytes.
'6869'.fromHex.asString "* -> hi
The character index of the first occurrence of the String argument, or nil if it does not occur.
'hello'.index:'l' "* -> 2
A copy with the String argument inserted before the given character index; an index at or past the end appends.
'hello'.insert:'-' at:2 "* -> he-llo
The number of characters (Unicode scalar values) -- not bytes.
'héllo'.length "* -> 5
A lowercase copy (full Unicode lowercasing).
'Hello'.lower "* -> hello
Left-justify to width by appending spaces; answers self if already that wide.
('hi'.padRight:5) + '|' "* -> hi |
A copy with every match of the pattern replaced by the String argument. The pattern's type selects the variant: a String replaces each literal occurrence, a Regex replaces each match.
'banana'.replace:'an' with:'AN' "* -> bANANa 'a1b22c'.replace:#/[0-9]+/ with:'#' "* -> a#b#c
The string itself -- the human rendering of a String adds no quotes or escapes (structural, quoted rendering is .pp's job).
The characters from from (inclusive) to to (exclusive) — the String twin of List#sliceFrom:to:: character-indexed, both ends clamp to the string, an inverted range answers ''.
'command'.sliceFrom:3 to:7 "* -> mand 'command'.sliceFrom:3 to:99 "* -> mand
Split on runs of whitespace — the word-splitting shortcut.
'one two three'.split "* -> #(one two three)
The pieces of the receiver around each occurrence of pat, taken as a literal String (not a regex).
'a,b,c'.split:',' "* -> #(a b c)
The pieces between occurrences of the literal String separator, as a List of Strings (for pattern-based splitting see Regex.split:).
'a,b,c'.splitString:',' "* -> #(a b c)
Whether the receiver starts with the String argument.
'hello'.starts?:'he' "* -> true
The receiver styled with color-markup attributes, as an ANSI value — the programmatic counterpart of writing the tag in an #ANSI'…' literal. The receiver is markup-escaped, so its own brackets stay literal; the result embeds safely in other ANSI strings (spans nest and restore).
'FAIL'.styled:'bold red' "* -> #ANSI'[bold red]FAIL[/]'
This String's UTF-8 bytes encoded as a base64 String.
'hi'.toBase64 "* -> aGk=
Parse the receiver as a decimal Integer; raises an error if the whole string is not one.
'42'.to_integer "* -> 42
An uppercase copy (full Unicode uppercasing).
'hello'.upper "* -> HELLO