Ricardo Alonzo
Ricardo Alonzo

Reputation: 73

Elixir regex replacing square brakets and comma

As mentioned above, the goal is to remove square brackets and commas.
My current solution is the following:

Given:

"[40.45694301152436, -3.6907402812214514]"
|> String.replace("[", "")
|> String.replace(",", "")
|> String.replace("]", "")
|> String.split(" ")
|> Enum.map(fn x -> String.to_float(x) end)

Output:

[40.45694301152436, -3.6907402812214514]

I know this can be compacted much more, but I've been looking at examples all day and all failed to do the job above.

Upvotes: 1

Views: 801

Answers (5)

Adam Millerchip
Adam Millerchip

Reputation: 23119

I think the comment on your question about using a JSON parser is best, followed by fhdhsni's simple answer. But here's a method that extracts the numbers, rather than replacing the brackets:

str = "[40.45694301152436, -3.6907402812214514]"
regex = ~r/([\d\.-]+), ([\d\.+-]+)/
Regex.run(regex, str, capture: :all_but_first) |> Enum.map(&String.to_float/1)

Output:

[40.45694301152436, -3.6907402812214514]

Upvotes: 0

Máté
Máté

Reputation: 2345

Apart from the string replace solutions, you can take a look at Code.eval_string as well.

This way the string will get parsed and you'll get back the list you're looking for;

{list, _} = Code.eval_string "[40.45694301152436, -3.6907402812214514]"
# {[40.45694301152436, -3.6907402812214514], []}

Upvotes: 0

Tim Lowrimore
Tim Lowrimore

Reputation: 2052

Here's another option, using String.slice:

"[40.45694301152436, -3.6907402812214514]" 
|> String.slice(1..-2) 
|> String.split(~r/,\s+/) 
|> Enum.map(&String.to_float/1)

Cheers!

Upvotes: 0

Onorio Catenacci
Onorio Catenacci

Reputation: 15333

While @fhdhsni has given you a great answer if your concern is readability I'd suggest abstracting the whole thing to a separate function like so:

defmodule T do 
    def parsefloats(stringtobeparsed) do
        stringtobeparsed
        |> String.replace("[", "")
        |> String.replace(",", "")
        |> String.replace("]", "")
        |> String.split(" ")
        |> Enum.map(fn x -> String.to_float(x) end)
    end
end   

Then you call it like so:

[x,y] = T.parsefloats("[40.45694301152436, -3.6907402812214514]")
# [40.45694301152436, -3.6907402812214514]
iex(3)> x
# 40.45694301152436
iex(4)> y
# -3.6907402812214514

Not any better in terms of more compact code but more readable I think.

Upvotes: 0

fhdhsni
fhdhsni

Reputation: 1629

Instead of a string, you can pass a regex to String.replace. In Elixir you can build a regex with ~r sigil.

"[40.45694301152436, -3.6907402812214514]"
|> String.replace(~r'[\[\],]', "")
|> String.split()
|> Enum.map(&String.to_float/1)

Upvotes: 4

Related Questions