ESC
Type to search...
S
Soli Docs

Strings

UTF-8 text with powerful built-in methods for manipulation, searching, and transformation.

Creating Strings

String Literals

Create strings using double quotes. Supports escape sequences for special characters.

# Basic string literals
let greeting = "Hello, World!";
let name = "Alice";
let empty = "";

# Escape sequences
let newline = "Line 1\nLine 2";
let tab = "Column1\tColumn2";
let quote = "She said \"Hello\"";
let backslash = "Path: C:\\Users\\name";

# Unicode characters
let emoji = "Hello \u{1F44B}";  # Hello with wave emoji
let unicode = "\u{00E9}";       # e with accent
Raw Strings

Raw strings don't process escape sequences - useful for paths and regex patterns.

# Raw strings - no escape processing
let path = r"C:\Users\name\Documents";
let regex = r"\d+\.\d+";

# Compare with regular strings
let regular = "C:\\Users\\name";  # Need double backslashes
let raw = r"C:\Users\name";       # Single backslashes work
Multiline Strings

Use triple quotes or bracket syntax for multiline strings. Preserves newlines and indentation.

# Triple quote syntax (recommended)
let poem = """The fog comes
on little cat feet.
It sits looking
over harbor and city.""";

# Bracket syntax [[ ]]
let story = [[Once upon
a time in
the wild west.]];

# HTML template example
let html = """

Welcome

This is a paragraph.

"""; # SQL query example let query = """SELECT id, name, email FROM users WHERE active = true ORDER BY created_at DESC""";

Note: Both syntaxes create raw strings (no escape processing). The leading newline and indentation are preserved as-is. Use trim() to remove leading/trailing whitespace if needed.

Concatenation

Join strings together using the + operator. Non-string values are automatically converted.

# Basic concatenation
let greeting = "Hello, " + "World!";  # "Hello, World!"

# Auto-conversion of other types
let message = "Value: " + 42;         # "Value: 42"
let result = "Pi is " + 3.14159;      # "Pi is 3.14159"
let status = "Active: " + true;       # "Active: true"

# Building strings
let name = "Alice";
let age = 30;
let intro = "My name is " + name + " and I am " + str(age) + " years old.";
String Interpolation

Embed expressions directly in strings using #{expression} syntax.

# Basic variable interpolation
let name = "World";
let greeting = "Hello #{name}!";           # "Hello World!"

# Arithmetic expressions
let a = 2;
let b = 3;
let result = "Sum is #{a + b}";             # "Sum is 5"

# Multiple interpolations
let first = "John";
let last = "Doe";
let full = "#{first} #{last}";              # "John Doe"

# Method calls
let text = "hello";
let upper = "Upper: #{text.upper()}";        # "Upper: HELLO"

# Array access
let items = ["Alice", "Bob"];
let first_item = "First: #{items[0]}";       # "First: Alice"

# Hash access
let person = {"name": "Charlie"};
let person_name = "Name: #{person["name"]}"; # "Name: Charlie"
Type Annotations

Optionally specify string types for clarity and type safety.

# Typed strings
let name: String = "Alice";
let message: String = "";

# String arrays
let names: String[] = ["Alice", "Bob", "Charlie"];

# Function parameters
def greet(name: String) -> String
    "Hello, " + name + "!"
end

Accessing Characters

Index Access

Access individual characters using zero-based indexing. Negative indices count from the end.

let str = "Hello, World!";

# Zero-based indexing
print(str[0]);    # "H" (first character)
print(str[7]);    # "W"

# Negative indexing
print(str[-1]);   # "!" (last character)
print(str[-2]);   # "d" (second to last)

# Out of bounds returns null
print(str[100]);  # null
String Immutability

Strings are immutable - methods return new strings rather than modifying the original.

let original = "hello";
let upper = upcase(original);

print(original);  # "hello" (unchanged)
print(upper);     # "HELLO" (new string)

# To "modify", reassign the variable
let text = "hello";
text = upcase(text);
print(text);  # "HELLO"

Built-in Functions

len(string)

Returns the number of characters in the string.

print(len("hello"));  # 5
print(len(""));       # 0
print(len("Hello, World!"));  # 13
str(value)

Convert any value to its string representation.

str(42)           # "42"
str(3.14)         # "3.14"
str(true)         # "true"
str(null)         # "null"
str([1, 2, 3])    # "[1, 2, 3]"
str({"a": 1})     # "{\"a\": 1}"
split(string, separator)

Splits a string into an array by the specified separator.

split("a,b,c", ",")         # ["a", "b", "c"]
split("hello world", " ")   # ["hello", "world"]
split("one--two--three", "--")  # ["one", "two", "three"]

# Split into characters
split("hello", "")          # ["h", "e", "l", "l", "o"]
join(array, separator)

Joins array elements into a string with the specified separator.

join(["a", "b", "c"], ",")      # "a,b,c"
join(["hello", "world"], " ")   # "hello world"
join([1, 2, 3], "-")            # "1-2-3"
join(["one"], ", ")             # "one"
substring(string, start, end?)

Extracts a portion of a string from start index to end index (exclusive).

substring("hello", 0, 2)    # "he"
substring("hello", 1, 4)    # "ell"
substring("hello", 2)       # "llo" (to end)
substring("hello", -3)      # "llo" (negative start)
contains(string, substring)

Checks if a string contains the specified substring.

contains("hello world", "world")  # true
contains("hello world", "foo")    # false
contains("hello", "")             # true (empty string always matches)
contains("", "hello")             # false
index_of(string, substring)

Finds the position of the first occurrence of a substring. Returns -1 if not found.

index_of("hello world", "world")  # 6
index_of("hello world", "o")      # 4 (first occurrence)
index_of("hello world", "foo")    # -1 (not found)
index_of("hello", "")             # 0
upcase(string) / downcase(string)

Convert a string to uppercase or lowercase.

upcase("hello")       # "HELLO"
upcase("Hello World") # "HELLO WORLD"

downcase("HELLO")       # "hello"
downcase("Hello World") # "hello world"
trim(string)

Removes whitespace from both ends of a string.

trim("  hello  ")     # "hello"
trim("\n\thello\n")   # "hello"
trim("hello")         # "hello" (no change)
replace(string, search, replacement)

Replace all occurrences of a substring with another string.

replace("hello world", "world", "Soli")  # "hello Soli"
replace("aaa", "a", "b")                  # "bbb" (replaces all)
replace("hello", "x", "y")                # "hello" (no match)

String Methods

.starts_with(prefix) / .ends_with(suffix)

Check if a string starts or ends with a given substring.

let url = "https://example.com/page";

url.starts_with("https://")  # true
url.starts_with("http://")   # false

url.ends_with("/page")       # true
url.ends_with(".html")       # false

# Practical use
let filename = "report.pdf";
if (filename.ends_with(".pdf"))
    print("PDF file detected");
end
.chars()

Convert string to an array of individual characters.

let str = "hello";
let chars = str.chars();
print(chars);  # ["h", "e", "l", "l", "o"]

# Iterate over characters
for (c in "Soli".chars())
    print(c);
end
# Output: S, o, l, i
.reverse()

Return a new string with characters in reverse order.

"hello".reverse()   # "olleh"
"Soli".reverse()    # "iloS"
"12345".reverse()   # "54321"

# Check palindrome
def is_palindrome(s: String) -> Bool
    let cleaned = downcase(s);
    cleaned == cleaned.reverse()
end
print(is_palindrome("racecar"));  # true
.repeat(n)

Repeat a string n times.

"ab".repeat(3)      # "ababab"
"-".repeat(10)      # "----------"
"ha".repeat(0)      # ""

# Create separator line
let separator = "=".repeat(40);
print(separator);  # ========================================
.pad_start(length, char?) / .pad_end(length, char?)

Pad a string to a specified length with a character (default is space).

"42".pad_start(5, "0")     # "00042"
"5".pad_start(3)           # "  5" (default space)

"hi".pad_end(5, ".")       # "hi..."
"test".pad_end(8)          # "test    "

# Format numbers
let price = str(9.99);
print(price.pad_start(10));  # "      9.99"
.empty?() / .blank?()

Check if string is empty or blank (empty or only whitespace).

"".empty?()       # true
"hello".empty?()  # false
"   ".empty?()    # false

"".blank?()       # true
"   ".blank?()    # true (only whitespace)
"\n\t".blank?()   # true
"hello".blank?()  # false

HTML Functions

html_escape(string)

Escape HTML special characters to prevent XSS attacks.

html_escape("<div class='test'>Hello</div>")
# "&lt;div class='test'&gt;Hello&lt;/div&gt;"

html_escape("Tom & Jerry")
# "Tom &amp; Jerry"

html_escape("5 > 3 && 3 < 5")
# "5 &gt; 3 &amp;&amp; 3 &lt; 5"
html_unescape(string)

Convert HTML entities back to their original characters.

html_unescape("&lt;div&gt;")
# "<div>"

html_unescape("Tom &amp; Jerry")
# "Tom & Jerry"
sanitize_html(string)

Remove dangerous HTML tags while keeping safe formatting tags.

sanitize_html("<b>Bold</b> <style>body{color:red}</style>")
# "<b>Bold</b> "

sanitize_html("<p>Hello</p><object data='file.swf'></object>")
# "<p>Hello</p>"

Common Patterns

Parsing and Formatting
# Parse CSV line
let csv_line = "Alice,30,Engineer";
let fields = split(csv_line, ",");
let name = fields[0];    # "Alice"
let age = int(fields[1]); # 30
let job = fields[2];     # "Engineer"

# Format currency
def format_currency(amount: Float) -> String
    let formatted = str(amount);
    "$" + formatted
end

# Parse URL query string
def parse_query(query: String) -> Hash
    let result = {};
    let pairs = split(query, "&");
    for (pair in pairs)
        let parts = split(pair, "=");
        if (len(parts) == 2)
            result[parts[0]] = parts[1];
        end
    end
    result
end
let params = parse_query("name=Alice&age=30");
# {"name": "Alice", "age": "30"}
Validation Helpers
# Basic email validation
def is_valid_email(email: String) -> Bool
    contains(email, "@") && contains(email, ".")
end

# Check minimum length
def has_min_length(str: String, min: Int) -> Bool
    len(str) >= min
end

# Check if string is numeric
def is_numeric(str: String) -> Bool
    if (str.empty?())
        return false;
    end
    for (c in str.chars())
        if (!contains("0123456789", c))
            return false;
        end
    end
    true
end

# Validate username
def is_valid_username(username: String) -> Bool
    let trimmed = trim(username);
    len(trimmed) >= 3 && len(trimmed) <= 20
end
Template Strings
# Simple template replacement
def template(str: String, vars: Hash) -> String
    let result = str;
    for (pair in entries(vars))
        let key = pair[0];
        let value = pair[1];
        result = replace(result, "{{" + key + "}}", str(value));
    end
    result
end

let tmpl = "Hello, {{name}}! You have {{count}} messages.";
let output = template(tmpl, {"name": "Alice", "count": 5});
# "Hello, Alice! You have 5 messages."

# Build HTML safely
def build_link(url: String, text: String) -> String
    "" + html_escape(text) + ""
end

String Class Methods

String literals are automatically wrapped in a String class instance that provides methods for manipulation and transformation. Each string value has access to these methods via dot notation.

to_string()

Returns the string value. Called automatically in REPL to display string values.

let greeting = "Hello, World!";
# In REPL, displays: Hello, World!
# Equivalent to: greeting.to_string()
length()

Returns the number of characters in the string.

let s = String.new("hello");
let len = s.length();  # 5
upcase() / downcase()

Converts the string to uppercase or lowercase.

let s = String.new("Hello World");
s.upcase();   # "HELLO WORLD"
s.downcase(); # "hello world"
trim()

Removes leading and trailing whitespace.

let s = String.new("  hello  ");
s.trim();  # "hello"
contains(substr) / starts_with(prefix) / ends_with(suffix)

Check if string contains, starts with, or ends with a substring.

let s = String.new("Hello, World!");
s.contains("World");    # true
s.starts_with("Hello"); # true
s.ends_with("!");       # true
split(delimiter)

Splits the string by delimiter and returns an array of parts.

let s = String.new("a,b,c");
let parts = s.split(",");  # ["a", "b", "c"]
String.new(value)

Creates a new String instance from various value types.

                        String.new(42);        # "42"
String.new(3.14);      # "3.14"
String.new(true);      # "true"
String.new([1, 2, 3]); # "[1, 2, 3]"
index_of(substr)

Returns the index of the first occurrence of substring, or -1 if not found.

let s = String.new("hello world");
s.index_of("world");  # 6
s.index_of("hello");  # 0
s.index_of("foo");    # -1
substring(start, end)

Extracts a substring from start to end (exclusive).

let s = String.new("hello world");
s.substring(0, 5).to_string();   # "hello"
s.substring(6, 11).to_string();  # "world"
replace(from, to)

Replaces all occurrences of 'from' with 'to'.

let s = String.new("hello world");
s.replace("world", "soli").to_string();  # "hello soli"
lpad(width, pad_char?) / rpad(width, pad_char?)

Pads the string to reach the specified width.

let s = String.new("hi");
s.lpad(5).to_string();     # "   hi"
s.rpad(5).to_string();     # "hi   "
s.lpad(5, "*").to_string(); # "***hi"