Reputation: 723
Is there any way to have String contains/regex in argument matching? For example, the string is "Some error happened". But I want it to match the substring "error happened". I tried this but it does not work:
defp status({:error, ~r/error happened/}, state) do
end
Upvotes: 5
Views: 6884
Reputation: 121000
Although the answer by @Dogbert is absolutely correct, there is a trick one could use when error messages can not be longer than, say, 140 symbols (aka twitter-sized error messages.)
defmodule Test do
@pattern "error happened"
defp status({:error, @pattern <> _rest }, state),
do: IO.puts "Matched leading"
Enum.each(1..140, fn i ->
defp status({:error,
<<_ :: binary-size(unquote(i)),
unquote(@pattern) :: binary,
rest :: binary>>}, state),
do: IO.puts "Matched"
end)
Enum.each(0..140, fn i ->
defp status({:error, <<_ :: binary-size(unquote(i))>>}, state),
do: IO.puts "Unmatched"
end)
# fallback
defp status({:error, message}, state) do
cond do
message =~ "error happened" -> IO.puts "Matched >140"
true -> IO.puts "Unatched >140"
end
end
def test_status({:error, message}, state),
do: status({:error, message}, state)
end
Tests:
iex|1 ▶ Test.test_status {:error, "sdf error happened sdfasdf"}, nil
Matched
iex|2 ▶ Test.test_status {:error, "sdf errors happened sdfasdf"}, nil
Unmatched
iex|3 ▶ Test.test_status {:error, "error happened sdfasdf"}, nil
Matched leading
iex|4 ▶ Test.test_status {:error,
...|4 ▷ String.duplicate(" ", 141) <> "error happened sdfasdf"}, nil
Matched >140
Upvotes: 1
Reputation: 222060
No, neither String contains nor Regex match can be done using either pattern matching or guard functions. Your best bet would be to match {:error, error}
in the pattern and do the string matching inside the function using e.g. cond
:
defp status({:error, error}, state) do
cond do
error =~ "error happened" -> ...
...
end
end
What can be done in pattern matching is a prefix match. If that's good enough for you, you can do this:
defp status({:error, "error happened" <> _}, state) do
This will match any string starting with "error happened"
.
Upvotes: 13