Can you use a Regular Expression inside a case
in Elixir?
So something along the lines of this:
case some_string do "string" -> # do something ~r/string[\d]+/ -> # do something _ -> # do something end
With case
it is not possible, but you can use cond
:
cond do some_string == "string" -> # do something String.match?(some_string, ~r/string[\d]+/) -> # do something true -> # do something end
The reason is that there is no way to hook into the pattern matching by calling special functions for specific values. I guess you got the idea from Ruby, which implements this by defining the special operator ===
. This will be implicitly called by Ruby's case statement and for a regex it will match the given value.
As Patrick said in his answer, there is nothing built-in for this, and cond
is probably your best option.
But to add another option and to show off the flexibility of Elixir: Since case
is just a macro in Elixir, you could implement your own macro like regex_case
to do this.
You should keep in mind that this might make the code harder to understand for new people on the project, but if you do a lot of regex matching, maybe the trade-off could make sense. You be the judge.
I implemented this a while ago, just to see that it was possible:
defmodule RegexCase do defmacro regex_case(string, do: lines) do new_lines = Enum.map lines, fn ({:->, context, [[regex], result]}) -> condition = quote do: String.match?(unquote(string), unquote(regex)) {:->, context, [[condition], result]} end # Base case if nothing matches; "cond" complains otherwise. base_case = quote do: (true -> nil) new_lines = new_lines ++ base_case quote do cond do unquote(new_lines) end end end end defmodule Run do import RegexCase def run do regex_case "hello" do ~r/x/ -> IO.puts("matches x") ~r/e/ -> IO.puts("matches e") ~r/y/ -> IO.puts("matches y") end end end Run.run
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With