Zenth has two kinds of string literals: double-quoted strings with interpolation, and single-quoted raw strings.
#Double-Quoted Strings
Double-quoted strings ("...") support interpolation with {expression}:
let name = "World";
Println("Hello, {name}!"); // Hello, World!Any expression can go inside the braces – variables, arithmetic, method calls:
let a = 3;
let b = 4;
Println("{a} + {b} = {a + b}"); // 3 + 4 = 7Values are automatically converted to strings, so you don’t need to call Str() inside interpolation:
let count = 42;
Println("There are {count} items"); // There are 42 items#Method Calls in Interpolation
You can call methods and access fields inside {}:
obj Rectangle {
width: Float;
height: Float;
fn area() -> Float {
return self.width * self.height;
}
}
let r = Rectangle(width=5.0, height=10.0);
Println("Area: {r.area()}"); // Area: 50#Plain Strings
If a double-quoted string has no {, it behaves as a plain string with no special processing:
Println("No interpolation here");#Escape Sequences
| Escape | Character |
|---|---|
\n | Newline |
\t | Tab |
\\ | Backslash |
\" | Double quote |
\{ | Literal { (prevents interpolation) |
\} | Literal } |
\0 | Null byte |
To include a literal brace in a double-quoted string, escape it:
Println("Use \{braces\} literally"); // Use {braces} literally#Single-Quoted Strings (Raw Strings)
Single-quoted strings ('...') never interpolate. Braces are treated as plain characters:
Println('Hello {name}'); // Hello {name}This is useful for strings that contain braces as literal text, such as templates, format strings, or code snippets.
Single-quoted strings support the same escape sequences as double-quoted strings, except \' instead of \":
| Escape | Character |
|---|---|
\n | Newline |
\t | Tab |
\\ | Backslash |
\' | Single quote |
\0 | Null byte |
#Multi-line Strings
Use triple double-quotes ("""...""") for multi-line string literals. The content between the opening and closing """ is preserved as-is, including newlines and indentation:
let text = """
Hello
World
""";
Println(text); // prints "Hello\nWorld"The first newline after the opening """ and the last newline before the closing """ are stripped, so the content is exactly what appears between them.
Multi-line strings support interpolation, just like regular double-quoted strings:
let name = "Zenth";
let msg = """
Welcome to {name}!
Enjoy coding.
""";They also support escape sequences (\n, \t, \\, \", \{, \}, \0).
Multi-line strings are useful for help text, templates, and any string that spans multiple lines:
Print("""
tasks — a pipe-delimited todo manager
Usage:
tasks list active tasks
tasks add 'title' add a new task
tasks done <id> mark a task as done
""");#String Concatenation
Strings can be concatenated with +:
let first = "Hello";
let last = "World";
let full = first + ", " + last;With interpolation, concatenation is rarely needed:
let full = "{first}, {last}";#String Conversion
Use Str() to convert other types to strings:
let n = 42;
let s = Str(n); // "42"
let f = Str(3.14); // "3.14"Inside interpolated strings, conversion is automatic – Str() is only needed when you need a string value outside of interpolation.
#Parsing with Base
Use .to_int(base) to parse a string as an integer in a given base (2-36):
let n = "ff".to_int(16); // 255
let b = "1010".to_int(2); // 10
let o = "77".to_int(8); // 63Without an argument, .to_int() parses as base 10.
#String Length
Use Len() or .length() to get the length of a string:
let s = "hello";
Println(Len(s)); // 5
Println(s.length()); // 5#Containment
Use .contains() to check if a string contains a substring:
let s = "hello world";
if s.contains("world") {
Println("found it");
}#Case Conversion
Use .upper() and .lower() for case conversion:
Println("hello".upper()); // HELLO
Println("HeLLo".lower()); // hello#Prefix and Suffix
Use .starts_with() and .ends_with() to check for prefixes and suffixes:
let name = "zenth";
Println(name.starts_with("zen")); // true
Println(name.ends_with("th")); // trueUse .strip_prefix() and .strip_suffix() to remove a prefix or suffix from a string. If the string does not have the given prefix/suffix, it is returned unchanged:
let line = "fold along x=5";
let spec = line.strip_prefix("fold along "); // "x=5"
let file = "photo.png";
let name = file.strip_suffix(".png"); // "photo"
// No match — returns unchanged
let same = "hello".strip_prefix("xyz"); // "hello"#Trimming
Use .strip() to trim whitespace, or pass characters to trim from both ends:
Println("--" + " hi ".strip() + "--"); // --hi--
Println("--" + "..hi..".strip(".") + "--"); // --hi--#Find, Count, Replace
Use .find() and .count() for substring search and counting:
Println("banana".find("na")); // 2
Println("banana".count("na")); // 2Use .replace(old, new) to replace all matches, or .replace(old, new, n) to limit replacements:
Println("a-b-a".replace("a", "x")); // x-b-x
Println("a-b-a".replace("a", "x", 1)); // x-b-aUse .sorted() to return a new string with its characters sorted. By default it sorts ascending; pass "desc" or order="desc" to reverse the order:
let s = "dbca";
Println(s.sorted()); // abcd
Println(s.sorted("desc")); // dcba
Println(s.sorted(order="desc")); // dcba#Splitting Strings
Use the .split() method to divide a string into an array of substrings (Array(Str)).
By default, .split() splits on whitespace. You can also pass a delimiter string:
let words = "this is zenth".split();
Println(words[0]); // "this"
let parts = "a-b-c".split("-");
Println(parts[1]); // "b"Use .split_once(sep) when you only need two pieces. It returns a tuple (left, right):
let (cmd, value) = "forward 10".split_once(" ");
Println(cmd); // "forward"
Println(value); // "10"#Character Classification
Use .is_digit() to check if a single-character string is a decimal digit (0–9):
Println("5".is_digit()); // true
Println("0".is_digit()); // true
Println("a".is_digit()); // false
Println("[".is_digit()); // falseThis is useful when iterating over a string character by character:
var digits = 0;
for ch in "abc123" {
if ch.is_digit() {
digits += 1;
}
}
Println(digits); // 3#Padding
Use .pad_left(width) and .pad_right(width) to pad a string to a minimum width. By default, padding uses spaces. Pass a second argument to specify a custom fill string:
// Space-padded (default)
Println("hello".pad_right(10)); // "hello "
Println("hello".pad_left(10)); // " hello"
// Custom fill character
Println("42".pad_left(5, "0")); // "00042"
Println("hi".pad_right(6, ".")); // "hi...."
// No padding if already wide enough
Println("toolong".pad_right(3)); // "toolong"This is especially useful for tabular CLI output:
let items = ["apples", "bread", "milk"];
let prices = ["1.50", "2.99", "3.25"];
for i, item in items {
Println(item.pad_right(10) + prices[i].pad_left(6));
}
// apples 1.50
// bread 2.99
// milk 3.25#Repeating
Use .repeat(n) to repeat a string n times:
let dots = ".".repeat(5); // "....."
let row = "ab".repeat(3); // "ababab"
let empty = "x".repeat(0); // ""This is useful for building grid rows, padding, or repeated patterns.
#Indexing
Indexing a string returns a one-character Str:
let s = "hello";
let first = s[0]; // "h"#Slicing
Use slicing syntax to extract a substring:
let s = "hello";
let tail = s[1:]; // "ello"
let head = s[:3]; // "hel"
let mid = s[1:4]; // "ell"String slicing is Unicode-aware (operates on runes, not bytes).