ExAequoBase.RegexParser (ExAequoBase v0.1.6)
View SourceParses an input string according to a list of regexen and associated actions
iex(1)> rgxen = [
...(1)> {~r/\A\s+/, ""}, # ignored, sort of
...(1)> {~r/\A\d+/, &String.to_integer/1},
...(1)> {~r/\A(,),/, ","},
...(1)> {~r/\A(,)/, :comma},
...(1)> {~r/\A(.+?)(?=,)/}
...(1)> ]
...(1)> parse(rgxen, " 42alpha,beta,, , ")
["", 42, "alpha", :comma, "beta", ",", "", :comma, ""]
In case we want to eliminate empty strings immediately we can use the special atom :ignore
iex(2)> rgxen = [
...(2)> {~r/\A\s+/, :ignore}, # ignored, sort of
...(2)> {~r/\A\d+/, &String.to_integer/1},
...(2)> {~r/\A(,),/, ","},
...(2)> {~r/\A(,)/, :comma},
...(2)> {~r/\A(.+?)(?=,)/}
...(2)> ]
...(2)> parse(rgxen, " 42alpha,beta,, , ")
[42, "alpha", :comma, "beta", ",", :comma]
It might be more efficent to tell the parser where the rest is
iex(3)> parse([{~r/\A(.)(.*)/}], "hello")
["h", "e", "l", "l", "o"]
We can also parse keywords
iex(4)> parse([{"hell"}, {"o"}], "hello")
["hell", "o"]
But we need to parse all parts of a string
iex(5)> assert_raise(Error, fn -> parse([{"a"}], "ab") end)
Summary
Types
@type atoms() :: [atom()]
@type binaries() :: [binary()]
@type error_t() :: {:error, binary()}
@type error_t(t) :: {:error, t}
@type maybe(t) :: nil | t
@type natural() :: non_neg_integer()
@type numbered(t) :: {t, number()}
@type numbered_lines_t() :: [numbered_line_t()]
@type ok_t() :: {:ok, any()}
@type ok_t(t) :: {:ok, t}
@type pair_t(t) :: {t, t}
@type pair_t(lt, rt) :: {lt, rt}
@type pairs_t() :: [pair_t()]
@type pairs_t(t) :: [pair_t(t)]
@type pairs_t(lt, rt) :: [pair_t(lt, rt)]
@type rgx_pair() :: {Regex.t(), ExAequoFn.NamedFn.t()}
@type rgx_pairs() :: [rgx_pair()]
@type specs_t() :: [spec_t()]
@type zero_fn_t() :: (-> any())
@type zero_fn_t(t) :: (-> t)