Current section
Files
Jump to
Current section
Files
lib/parser.ex
defmodule MT940.Parser do
def parse(raw) when is_binary(raw) do
raw
|> String.strip
|> String.split(Regex.compile!("(\R?):\\d{1,2}\\w?:()"), on: :all_but_first, trim: true)
|> Stream.map(&String.strip/1)
|> Stream.chunk(2)
|> Stream.map(fn [k, v] -> {k |> remove_newline |> String.to_atom(), split(k, v)} end)
|> Enum.into(Keyword.new)
end
defp split(":25:", v) do
case v |> String.contains?("/") do
true -> ~r/^(\d{8}|\w{8,11})\/(\d{1,23})(\D{3})?$/
false -> ~r/^(\w+)(\D{3})?$/
end
|> Regex.run(v, capture: :all_but_first)
|> List.to_tuple
end
defp split(":28C:", v) do
~r/^(\d+)\/(\d+)$/
|> Regex.run(v, capture: :all_but_first)
|> Enum.map(&String.to_integer/1)
|> List.to_tuple
end
defp split(":60" <> <<_>> <> ":", v) do
v |> remove_newline |> balance
end
defp split(":61:", v) do
~r/^(\d{6})(\d{4}?)(C|RC|D|RD)(\D)?([0-9,]{4,15})(\w{4})(NONREF|.{1,22})(\/\/)?(\w{0,16})?([\s\R]{1,2})?(.{0,34})?$/
|> Regex.run(v, capture: :all_but_first)
end
defp split(":86:", v) do
s = ~r/^(\d{3})(.)/
|> Regex.run(v, capture: :all_but_first)
case s do
[code, separator] ->
fields = v
|> remove_newline
|> String.split(Regex.compile!("(^\\d{3})?(\\#{separator})\\d{2}()"), on: :all_but_first, trim: true)
|> Stream.chunk(2)
|> Stream.map(fn [k, v] -> {String.to_integer(k), v} end)
|> Enum.into(HashDict.new)
{code, fields}
_ ->
Regex.split(~r/\R/, v)
end
end
defp split(":62" <> <<_>> <> ":", v) do
v |> remove_newline |> balance
end
defp split(":90" <> <<_>> <> ":", v) do
~r/^(\d{1,5})(\w{3})([0-9,]{1,15})$/
|> Regex.run(v, capture: :all_but_first)
|> List.to_tuple
end
defp split(_, v) when is_binary(v) do
v
end
defp balance(v) do
~r/^(\w{1})(\d{6})(\w{3})([0-9,]{1,15}).*$/
|> Regex.run(v, capture: :all_but_first)
|> List.to_tuple
end
defp remove_newline(string) when is_binary(string) do
~r(\R) |> Regex.replace(string, "")
end
end