Strings and Text

In this chapter you will learn:

  • The two string literal types (raw and c-strings)
  • How to embed expressions in strings using {...} syntax
  • How strings with anaphora become functions
  • Format specifiers for controlling output
  • The string functions available in the str namespace

String Literal Types

Eucalypt has two kinds of string literal: raw strings and c-strings.

Raw Strings

A plain double-quoted string is a raw string — backslashes are literal characters with no escape processing. This is convenient for regular expression usage.

greeting: "Hello, World!"
path: "C:\Users\alice\docs"
regex: "^\d+\.\d+"

The r"..." prefix is equivalent and can be used for clarity when the string contains backslashes:

path: r"C:\Users\alice\docs"
regex: r"^\d+\.\d+"

Raw strings support interpolation with {...}. Use {{ and }} for literal braces.

C-Strings (c"...")

If you require C-style escapes, you can use C-strings:

EscapeMeaning
\nNewline
\tTab
\rCarriage return
\\Literal backslash
\"Literal quote
\{, \}Literal braces
\xHHHex byte
\uHHHHUnicode code point
\UHHHHHHHHExtended Unicode
multiline: c"first line\nsecond line"

C-strings also support interpolation with {...}.

Basic Interpolation

Embed any expression inside a string using curly braces:

name: "World"
greeting: "Hello, {name}!"
name: World
greeting: Hello, World!

Interpolation braces accept names and dotted lookups. To use a computed value, bind it to a name first:

x: 3
y: 4
sum: x + y
result: "{x} + {y} = {sum}"
x: 3
y: 4
sum: 7
result: 3 + 4 = 7

Nested Lookups in Interpolation

You can use dotted paths inside interpolation:

data: { foo: { bar: 99 } }
label: "{data.foo.bar}"
data:
  foo:
    bar: 99
label: '99'

Note: Interpolation braces accept names and dotted lookups, but not arbitrary eucalypt expressions. If you need a computed value, bind it to a name first:

sum: x + y
result: "{sum}"

Escaping Braces

To include a literal brace in a string, double it:

example: "Use {{braces}} for interpolation"
example: Use {braces} for interpolation

This is also needed in regular expressions within interpolated strings:

pattern: "01234" str.match-with("\d{{4}}")

Format Specifiers

Add a format specifier after a colon inside the interpolation braces. These use printf-style format codes:

pi: 3.14159
formatted: "{pi:%.2f}"
padded: "{42:%06d}"
pi: 3.14159
formatted: '3.14'
padded: '000042'

String Anaphora

When a string contains {} (empty braces) or {0}, {1}, etc., the string literal actually defines a function rather than a plain string value:

eu -e '["a", "b", "c"] map("item: {}")'
- 'item: a'
- 'item: b'
- 'item: c'

Numbered anaphora control argument order:

reverse-pair: "{1},{0}"
result: reverse-pair(:a, :b)
result: b,a

You can mix named references and anaphora:

prefix: "Hello"
greet: "{prefix} {}!"
result: greet("World")
prefix: Hello
result: Hello World!

String Functions

The str namespace contains functions for working with strings.

Conversion

eu -e '42 str.of'
'42'

Case Conversion

eu -e '"hello" str.to-upper'
HELLO
eu -e '"GOODBYE" str.to-lower'
goodbye

Splitting and Joining

Split a string on a pattern:

eu -e '"one-two-three" str.split-on("-")'
- one
- two
- three

Join a list of strings:

eu -e '["a", "b", "c"] str.join-on(", ")'
a, b, c

Prefix and Suffix

eu -e '"world" str.prefix("hello ")'
hello world
eu -e '"hello" str.suffix("!")'
hello!

Characters and Letters

eu -e '"hello" str.letters'
- h
- e
- l
- l
- o
eu -e '"hello" str.letters count'
5

Regular Expressions

Testing a Match

eu -e '"hello" str.matches?("^h.*o$")'
true

Extracting Matches

str.match-with returns the full match and capture groups:

eu -e '"192.168.0.1" str.match-with("(\d+)[.](\d+)[.](\d+)[.](\d+)") tail'
- '192'
- '168'
- '0'
- '1'

str.matches-of returns all occurrences of a pattern:

eu -e '"192.168.0.1" str.matches-of("\d+")'
- '192'
- '168'
- '0'
- '1'

Base64 and SHA-256

eu -e '"hello" str.base64-encode'
aGVsbG8=
eu -e '"hello" str.sha256'
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Practical Examples

Generating URLs

base: "https://api.example.com"
endpoints: ["users", "posts", "comments"] map("{base}/{}")
base: https://api.example.com
endpoints:
- https://api.example.com/users
- https://api.example.com/posts
- https://api.example.com/comments

Formatting a Table

rows: [
  { name: "Alice" score: 85 }
  { name: "Bob" score: 92 }
]

` :suppress
format-row(r): "{r.name:%10s} | {r.score:%3d}"

table: rows map(format-row)

Key Concepts

  • Interpolation uses {expression} inside double-quoted strings
  • Empty braces {} and numbered braces {0}, {1} create string functions (anaphora)
  • Format specifiers follow a colon: {value:%06d}
  • Escape literal braces by doubling them: {{ and }}
  • The str namespace provides splitting, joining, case conversion, matching, and more