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 " + age.to_s + " 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 = original.upcase
print(original) # "hello" (unchanged)
print(upper) # "HELLO" (new string)
# To "modify", reassign the variable
let text = "hello"
text = text.upcase
print(text) # "HELLO"
String Methods
All string methods are called with dot notation on string values.
.length / .len / .size
Returns the number of characters in the string.
"hello".length # 5
"hello".size # 5
"".len # 0
.bytesize / .bytes
bytesize returns the number of bytes (UTF-8). bytes returns the byte values as an array.
"hello".bytesize # 5
"hello".bytes # [104, 101, 108, 108, 111]
.empty? / .blank? / .present?
Check if string is empty, blank (empty or only whitespace), or present (not blank).
"".empty? # true
"hello".empty? # false
" ".empty? # false
"".blank? # true
" ".blank? # true (only whitespace)
"hello".blank? # false
"hello".present? # true
"".present? # false
" ".present? # false
.inspect / .class / .is_a?(type) / .nil?
Introspection methods for debugging and type checking.
"hello".inspect # "\"hello\""
"hello".class # "String"
"hello".is_a?("String") # true
"hello".nil? # false
.upcase / .downcase / .capitalize / .swapcase
Case conversion methods. uppercase and lowercase are aliases for upcase and downcase.
"hello".upcase # "HELLO"
"HELLO".downcase # "hello"
"hello".capitalize # "Hello"
"Hello World".swapcase # "hELLO wORLD"
# Aliases
"hello".uppercase # "HELLO"
"HELLO".lowercase # "hello"
.contains(substr) / .includes?(substr)
Checks if the string contains a substring. includes? is an alias.
"hello world".contains("world") # true
"hello world".contains("foo") # false
"hello".includes?("ell") # true
.starts_with(prefix) / .ends_with(suffix)
Check if a string starts or ends with a given substring. Also available as starts_with? and ends_with?.
"https://example.com".starts_with("https://") # true
"report.pdf".ends_with(".pdf") # true
# With ? suffix (alias)
"hello".starts_with?("he") # true
"hello".ends_with?("lo") # true
.index_of(substr)
Returns the index of the first occurrence of a substring, or -1 if not found.
"hello world".index_of("world") # 6
"hello world".index_of("o") # 4
"hello world".index_of("foo") # -1
.count(substr)
Counts the number of occurrences of a substring.
"hello".count("l") # 2
"banana".count("ana") # 1
"hello".count("x") # 0
.match(pattern) / .scan(pattern)
match returns the first regex match. scan returns all matches as an array.
"hello 42 world 7".match(r"\d+") # "42"
"hello 42 world 7".scan(r"\d+") # ["42", "7"]
.trim / .strip / .lstrip / .rstrip / .chomp
Whitespace removal. trim (alias strip) removes both sides, lstrip/rstrip remove left/right only, chomp removes trailing newlines.
" hello ".trim # "hello"
" hello ".strip # "hello" (alias)
" hello ".lstrip # "hello "
" hello ".rstrip # " hello"
"hello\n".chomp # "hello"
.squeeze
Collapses runs of repeated characters into a single character.
"aaabbbccc".squeeze # "abc"
"hello world".squeeze # "helo world"
.reverse
Returns a new string with characters in reverse order.
"hello".reverse # "olleh"
"12345".reverse # "54321"
.replace(search, replacement) / .gsub(pattern, replacement) / .sub(pattern, replacement)
replace replaces all occurrences. gsub replaces all regex matches. sub replaces first regex match only.
"hello world".replace("world", "Soli") # "hello Soli"
"aaa".replace("a", "b") # "bbb"
"hello 42 world 7".gsub(r"\d+", "X") # "hello X world X"
"hello 42 world 7".sub(r"\d+", "X") # "hello X world 7"
.tr(from, to)
Translates characters: replaces each character in from with the corresponding character in to.
"hello".tr("aeiou", "*") # "h*ll*"
"hello".tr("el", "ip") # "hippo"
.delete(chars) / .delete_prefix(prefix) / .delete_suffix(suffix)
delete removes all occurrences of specified characters. delete_prefix/delete_suffix remove a specific prefix or suffix.
"hello".delete("lo") # "he"
"Hello, World!".delete_prefix("Hello, ") # "World!"
"report.pdf".delete_suffix(".pdf") # "report"
.insert(index, string)
Inserts a string at the specified index position.
"helo".insert(3, "l") # "hello"
"world".insert(0, "hello ") # "hello world"
.truncate(length)
Truncates the string to the specified length.
"hello world".truncate(5) # "hello"
"hi".truncate(10) # "hi"
.substring(start, end?)
Extracts a portion of the string from start index to end index (exclusive).
"hello".substring(0, 2) # "he"
"hello".substring(2) # "llo"
"hello".substring(-3) # "llo"
.split(separator) / .join(separator)
split splits a string into an array. join joins characters back with a separator.
"a,b,c".split(",") # ["a", "b", "c"]
"hello world".split(" ") # ["hello", "world"]
"hello".split("") # ["h", "e", "l", "l", "o"]
.chars / .lines
chars splits into individual characters. lines splits by newlines.
"hello".chars # ["h", "e", "l", "l", "o"]
"line1\nline2\nline3".lines # ["line1", "line2", "line3"]
for (c in "Soli".chars)
print(c)
end
.partition(separator) / .rpartition(separator)
Splits into 3 parts: [before, separator, after]. rpartition searches from the right.
"hello-world-test".partition("-") # ["hello", "-", "world-test"]
"hello-world-test".rpartition("-") # ["hello-world", "-", "test"]
.lpad(width, char?) / .rpad(width, char?) / .center(width, char?)
Pad a string to a specified width. ljust/rjust are aliases for rpad/lpad.
"42".lpad(5, "0") # "00042"
"hi".rpad(5, ".") # "hi..."
"hi".center(7, "-") # "--hi---"
# Default pad char is space
"5".lpad(3) # " 5"
"hi".rpad(5) # "hi "
.ord / .chr / .hex / .oct
Character encoding conversions. ord returns the Unicode code point, chr returns the character, hex/oct convert to hexadecimal/octal representation.
"A".ord # 65
"A".hex # "41"
"A".oct # "101"
.to_i / .to_f / .to_s / .to_string / .to_sym / .parse_json
Type conversion methods. to_int/to_float are aliases for to_i/to_f.
"42".to_i # 42
"3.14".to_f # 3.14
42.to_s # "42"
[1,2,3].to_string # "[1, 2, 3]"
# Convert to symbol
"name".to_sym # :name
"hello".to_sym # :hello
# Parse JSON
'{"name":"Alice"}'.parse_json # {"name": "Alice"}
"[1,2,3]".parse_json # [1, 2, 3]
"not json".parse_json # {}
HTML Functions
html_escape(string)
Escape HTML special characters to prevent XSS attacks.
html_escape("<div class='test'>Hello</div>")
# "<div class='test'>Hello</div>"
html_escape("Tom & Jerry")
# "Tom & Jerry"
html_escape("5 > 3 && 3 < 5")
# "5 > 3 && 3 < 5"
html_unescape(string)
Convert HTML entities back to their original characters.
html_unescape("<div>")
# "<div>"
html_unescape("Tom & 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 = csv_line.split(",")
let name = fields[0] # "Alice"
let age = fields[1].to_i # 30
let job = fields[2] # "Engineer"
# Parse URL query string
def parse_query(query: String) -> Hash
let result = {}
let pairs = query.split("&")
for (pair in pairs)
let parts = pair.split("=")
if (parts.length == 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
email.contains("@") && email.contains(".")
end
# Check minimum length
def has_min_length(s: String, min: Int) -> Bool
s.length >= min
end
# Check if string is numeric
def is_numeric(s: String) -> Bool
if (s.empty?)
return false
end
for (c in s.chars)
if (!"0123456789".contains(c))
return false
end
end
true
end
# Validate username
def is_valid_username(username: String) -> Bool
let trimmed = username.trim
trimmed.length >= 3 && trimmed.length <= 20
end
Template Strings
# Simple template replacement
def template(text: String, vars: Hash) -> String
let result = text
for (pair in entries(vars))
let key = pair[0]
let value = pair[1]
result = result.replace("{{" + key + "}}", value.to_string)
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