Strings and Charlists

Elixir strings, charlists, string functions, interpolation, and binary manipulation

Elixir has two string-like types: binaries (UTF-8 strings) and charlists (lists of integer codepoints).

Strings (binaries)

Strings are UTF-8 encoded binaries enclosed in double quotes:

name = "Elixir"
"This is #{name}"       # => "This is Elixir" (interpolation)

String.length("café")   # => 4  (graphemes)
byte_size("café")       # => 5  (bytes, é is 2 bytes)

Common String functions

Function Example Result
String.upcase/1 String.upcase("hello") "HELLO"
String.downcase/1 String.downcase("HELLO") "hello"
String.capitalize/1 String.capitalize("elixir") "Elixir"
String.trim/1 String.trim(" hi ") "hi"
String.trim_leading/1 String.trim_leading(" hi") "hi"
String.trim_trailing/1 String.trim_trailing("hi ") "hi"
String.split/2 String.split("a,b,c", ",") ["a", "b", "c"]
String.replace/3 String.replace("hi", "i", "ello") "hello"
String.contains?/2 String.contains?("elixir", "lix") true
String.starts_with?/2 String.starts_with?("elixir", "el") true
String.ends_with?/2 String.ends_with?("elixir", "ir") true
String.slice/3 String.slice("elixir", 1, 3) "lix"
String.at/2 String.at("elixir", 0) "e"
String.reverse/1 String.reverse("elixir") "rixile"
String.length/1 String.length("café") 4
String.graphemes/1 String.graphemes("noël") ["n", "o", "ë", "l"]
String.codepoints/1 String.codepoints("é") ["é"]
String.to_integer/1 String.to_integer("42") 42
String.to_float/1 String.to_float("3.14") 3.14
String.pad_leading/3 String.pad_leading("5", 3, "0") "005"
String.pad_trailing/3 String.pad_trailing("5", 3, "0") "500"
String.match?/2 String.match?("abc", ~r/b/) true

Charlists

Charlists are lists of integer codepoints, written with single quotes:

'hello'  # => [104, 101, 108, 108, 111]

# Convert between types
String.to_charlist("hello")   # => 'hello'
List.to_string('hello')       # => "hello"

Charlists are typically used when interfacing with Erlang libraries.

Sigils

# ~s = string (supports interpolation)
~s(Hello #{name})           # => "Hello Elixir"

# ~S = string (no interpolation)
~S(Hello #{name})           # => "Hello \#{name}"

# ~c = charlist
~c(hello)                   # => 'hello'

# ~r = regex
~r/hello/i                  # => ~r/hello/i

# ~w = word list
~w(foo bar baz)a            # => [:foo, :bar, :baz]
~w(foo bar baz)s            # => ["foo", "bar", "baz"]
~w(foo bar baz)c            # => ['foo', 'bar', 'baz']

# Custom delimiters
~s|hello "world"|           # => "hello \"world\""
~s{hello {nested}}          # => "hello {nested}"

Concatenation

# String concatenation
"hello" <> " " <> "world"   # => "hello world"

# List concatenation (charlists)
'hello' ++ ' world'         # => 'hello world'

Binary pattern matching

Since strings are binaries, you can pattern match on them:

<<first, rest::binary>> = "hello"
first  # => 104 (h)
rest   # => "ello"

<<h::utf8, e::utf8, l::utf8>> = "hel"
h  # => 104
e  # => 101