在Elixir中将字符串转换为地图

时间:2019-03-08 12:11:11

标签: parsing elixir

我有一个类似这样的字符串:

 ### image_date: 23/01/2019 ### 
    pool2 wxcs 2211
    pool3 wacs 1231
 ### line_count: 1 ###

我想将其转换为地图,例如:

%{
  image_data: "23/01/2019",
  content: "pool2 wxcs 2211\npool3 wacs 1231",
  line_count: 1
}

有人可以帮我吗?

2 个答案:

答案 0 :(得分:1)

一个人可能会使用Regex.scan/3

for [capture] <- Regex.scan(~r/(?<=###).*?(?=###)/mus, str), into: %{} do
  case capture |> String.split(":") |> Enum.map(&String.trim/1) do
    [name, value] -> {name, value}
    [content] -> {"content", content}
  end
end

导致:

#⇒ %{
#  "content" => "pool2 wxcs 2211\n    pool3 wacs 1231",
#  "image_date" => "23/01/2019",
#  "line_count" => "1"
# }

答案 1 :(得分:0)

虽然不漂亮,但确实可以完成工作。

defmodule UglyParser do
  def main do
    str = """
    ### image_date: 23/01/2019 ###
        pool2 wxcs 2211
        pool3 wacs 1231
    ### line_count: 1 ###
    """

    [header, content, footer] = String.split(str, ~r/(?:#\s*\n)|(?:\n\s*#)/, trim: true)

    header = to_pair(header)
    footer = to_pair(footer)
    content = {:content, String.trim(content) |> String.replace(~r/\n\s*/, "\n")}

    Enum.into([header, footer, content], %{})
  end

  defp to_pair(str) do
    String.replace(str, "#", "")
    |> String.trim()
    |> String.split(": ")
    |> (fn [key, value] -> {String.to_atom(key), value} end).()
  end
end