有没有办法在参数匹配中进行字符串包含/正则表达式匹配? 例如,字符串是“发生了一些错误”。但我想匹配子字符串“错误发生了”。我尝试过这个方法,但它不起作用:
defp status({:error, ~r/error happened/}, state) do
end
有没有办法在参数匹配中进行字符串包含/正则表达式匹配? 例如,字符串是“发生了一些错误”。但我想匹配子字符串“错误发生了”。我尝试过这个方法,但它不起作用:
defp status({:error, ~r/error happened/}, state) do
end
不,无论是使用模式匹配还是守卫函数都不能进行字符串包含或正则表达式匹配。最好的方法是在模式中匹配{: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"
开头的任何字符串。
虽然@Dogbert的答案绝对正确,但是当错误消息不能超过140个字符(也就是Twitter大小的错误消息)时,有一个技巧可以使用。
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