【问题标题】:Elixir method pattern matching with string containsElixir 方法模式匹配字符串包含
【发布时间】:2017-12-03 00:39:05
【问题描述】:

有没有办法让字符串包含/正则表达式在参数匹配中? 例如,字符串是“发生了一些错误”。但我希望它与子字符串“发生错误”相匹配。我试过了,但它不起作用:

  defp status({:error, ~r/error happened/}, state) do

  end

【问题讨论】:

    标签: pattern-matching elixir


    【解决方案1】:

    虽然@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
    

    【讨论】:

      【解决方案2】:

      不,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" 开头的字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-10
        • 1970-01-01
        • 1970-01-01
        • 2019-09-07
        • 1970-01-01
        • 2019-04-24
        • 1970-01-01
        • 2015-04-23
        相关资源
        最近更新 更多