【发布时间】:2017-12-03 00:39:05
【问题描述】:
有没有办法让字符串包含/正则表达式在参数匹配中? 例如,字符串是“发生了一些错误”。但我希望它与子字符串“发生错误”相匹配。我试过了,但它不起作用:
defp status({:error, ~r/error happened/}, state) do
end
【问题讨论】:
有没有办法让字符串包含/正则表达式在参数匹配中? 例如,字符串是“发生了一些错误”。但我希望它与子字符串“发生错误”相匹配。我试过了,但它不起作用:
defp status({:error, ~r/error happened/}, state) do
end
【问题讨论】:
虽然@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
【讨论】:
不,String contains 和 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" 开头的字符串。
【讨论】: