shahryarjb
What is the best way for Parsing a string and convert to map
Hello, I wanted to use the NimbleParsec library to convert a string into the map I need. But I think I got it wrong and this is more for me to equle with something and not to make the output I need like regex. it’s true?
For example I have this string
"sanitize(trim, lowercase) validate(not_empty, max_len = 20)"
# And I need something like this:
# Output: %{sanitize: ['trim', 'lowercase'], validate: ['not_empty', {'max_len', '20'}]}
It should be a bit dynamic for example:
"sanitize(trim, lowercase, downcase, replace= T) validate(not_empty, max_len = 20, not_integer)"
# Output: %{sanitize: ['trim', 'lowercase', 'downcase', {'replace', 'T'}], validate: ['not_empty', {'max_len', '20'}, 'not_integer']}
Now, without regex is there a good way? or NimbleParsec can create something like this?
It should be noted I have many items for each part like `trim, lowercase, downcase and etc..
Thank you in advance
Most Liked
hst337
The shortest solution is
for line in String.split(input, ")"), do: Code.string_to_quoted!(line <> ")")
LostKobrakai
NimbleParsec is not regex. It’s not “searching” through your input.
A parser works by going though the input string front → end and at each step you need to define what can be matched next. In your example you tell it to match either "validate" or "sanitize". It starts from the front, finds "sanitize" and then the next char is (, which matches neither of your expected values, so parsing halts.
NimbleParsec — NimbleParsec v1.3.1 has an example of something similar, parsing things wrapped in " instead of parenthesis.
cmo
With NimbleParsec, you create rules for the things you want to parse and then define a parser, e.g parsing a gmail-like search string. Should be pretty straight forward to parse your text format.
...
field =
choice([
string("message:") |> replace(:message),
string("user:") |> replace(:user),
string("ip:") |> replace(:ip)
])
|> ignore(optional(whitespace))
param =
repeat(
lookahead_not(concat(optional(whitespace), choice([field, value_field, time_field])))
|> optional(whitespace)
|> utf8_string([not: ?\s], min: 1)
)
|> ignore(choice([whitespace, eos()]))
|> post_traverse(:join)
...
defparsec :parse_search_string,
ignore(optional(whitespace))
|> times(
choice([
concat(field, param),
value_field_param,
time_field
])
|> post_traverse(:group)
|> ignore(optional(whitespace)),
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









