index

Tips for Binary Pattern Matching

elixir-lang.org tutorial

documentation

Use ? for character identity

In [1]:
?a
Out[1]:
97
In [2]:
<<98>> == <<?b>>
Out[2]:
true
In [4]:
<<?g, ?o, ?\n>> == "go
"
Out[4]:
true

Quotes can also be used

In [6]:
<<"a">> == <<?a>>
Out[6]:
true
In [13]:
<<"[", x :: utf8, "]">> = "[a]"
<<x>>
Out[13]:
"a"

A match group without a known length can only come at the end of a pattern

In [6]:
<<num :: size(16), rest::binary>> = <<1, 0, ?a, ?b, ?c>>
{num, rest}
Out[6]:
{256, "abc"}
In [7]:
<<line :: binary, ?\n>> = "this will not work
"
** (CompileError) "nofile":1 "a binary field without size is only allowed at the end of a binary pattern"

<> is allowed in matches

In [8]:
"foo" <> rest = "foobar"
rest
Out[8]:
"bar"

binary-size and unit(8)-size mean different things

In [9]:
<<x :: binary-size(5)>> = "frail"
x
Out[9]:
"frail"
In [11]:
<<x :: unit(8)-size(5)>> = "frail"
x
Out[11]:
440005650796

Matching length and resusing later in a pattern is useful

In [13]:
<<len :: size(2), msg :: size(len)>> = <<0b1001 :: size(4)>>
msg
Out[13]:
1
In [3]:
# also works in reverse order
<<msg :: size(len), len :: size(2)>> = <<0b1010 :: size(4)>>
msg
Out[3]:
2
In [4]:
# Can only be passed as part of the binary itself
{hlen, blen, <<header :: binary-size(hlen), body :: binary-size(blen)>>} = {4, 4, "headbody"}
** (CompileError) "nofile":1 "variable hlen@1 is unbound"
In [5]:
# or as a previously bound variable
{hlen, blen} = {4, 4}
<<header :: binary-size(hlen), body :: binary-size(blen)>> = "headbody"
{header, body}
Out[5]:
{"head", "body"}