Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular Expressions in Elixir case

Tags:

regex

elixir

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 
like image 820
Daisuke Shimamoto Avatar asked Jan 07 '16 07:01

Daisuke Shimamoto


2 Answers

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.

like image 132
Patrick Oscity Avatar answered Sep 16 '22 14:09

Patrick Oscity


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 
like image 34
Henrik N Avatar answered Sep 18 '22 14:09

Henrik N