字符串/二进制参数结束时的模式匹配

时间:2015-09-08 02:37:38

标签: elixir

我目前正在Elixir写一个小试飞员。我想使用模式匹配来评估文件是否符合规范格式(以" _spec.exs"结尾)。有很多关于如何在字符串的开头进行模式匹配的教程,但是它不知何故不能在字符串结尾处工作:

defp filter_spec(file <> "_spec.exs") do
  run_spec(file)
end

defp run_spec(file) do
  ...
end

这总是在编译错误中结束:

== Compilation error on file lib/monitor.ex ==
** (CompileError) lib/monitor.ex:13: a binary field without size is only allowed at the end of a binary pattern
    (stdlib) lists.erl:1337: :lists.foreach/2
    (stdlib) erl_eval.erl:669: :erl_eval.do_apply/6

有没有解决方案?

4 个答案:

答案 0 :(得分:7)

在Elixir入门指南中查看此link,似乎不可能。相关章节指出:

  

但是,我们可以匹配二进制修饰符的其余部分:

iex> <<0, 1, x :: binary>> = <<0, 1, 2, 3>>
<<0, 1, 2, 3>>
iex> x
<<2, 3>>
  

上述模式仅在二进制文件位于<<>>末尾时才有效。使用字符串连接运算符<>

可以实现类似的结果
iex> "he" <> rest = "hello"
"hello"
iex> rest
"llo"

由于字符串是Elixir中的二进制文件,因此对于它们来说也不可能匹配后缀。

答案 1 :(得分:1)

正如其他答案所提到的,这在elixir / erlang中是不可能的。然而,另一个解决方案是使用Path模块解决问题,因此对于您的用例,您应该能够执行以下操作:

dir_path
  |> Path.join( "**/*_spec.exs" )
  |> Path.wildcard

答案 2 :(得分:1)

检查匹配:

String.ends_with? filename, "_spec.exs"

提取文件:

file = String.trim_trailing filename, "_spec.exs"

答案 3 :(得分:0)

如果您预先计算了要匹配的二进制文件的长度,则可以在末尾进行匹配。像这样:

    file = "..."
    postfix = "_spec.exs"
    skip_chars = byte_size(file) - bytes_size(postfix)
    <<_ :: binary-size(skip_chars), post :: little-16>> = file

您可以将其放在函数中,但不能放在模式匹配子句中。我相信您可以很容易地将其扩展为使用utf8而不是二进制文件