在参数匹配中是否有任何方法可以使用String contains / regex? 例如,字符串是“发生了一些错误”。但我希望它匹配子串“发生错误”。我尝试了这个,但它不起作用:
defp status({:error, ~r/error happened/}, state) do
end
答案 0 :(得分:6)
不可以使用模式匹配或保护功能来完成String包含和Regex匹配。您最好的选择是匹配模式中的{:error, error}
并使用例如函数内的字符串匹配进行匹配。 cond
:
defp status({:error, error}, state) do
cond do
error =~ "error happened" -> ...
...
end
end
模式匹配可以做的是前缀匹配。如果这对您来说足够好,您可以这样做:
defp status({:error, "error happened" <> _}, state) do
这将匹配以"error happened"
开头的任何字符串。
答案 1 :(得分:0)
虽然@Dogbert的答案是绝对正确的,但是当错误消息不能超过140个符号(也就是推特大小的错误消息)时,可以使用一种技巧。
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
试验:
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