Elixir中子串的模式匹配

时间:2018-01-12 17:16:12

标签: elixir

如何在字符串上进行模式匹配,其中传递分号的任一侧将返回true?换句话说,是否有一种简单的模式匹配方式,它包含子字符串?

@matched_string "x-wat"

def match(@matched_string), do: true

match("x-wat") # true
match("x-wat; s-wat") # true
match("s-wat; x-wat") # true
match("s-wat") # false
match("x-wat-y") #false

2 个答案:

答案 0 :(得分:9)

不,这不能通过模式匹配来完成。您可以匹配字符串的前缀,或者如果您知道字符串开头的每个部分的长度,您可以指定它们的大小并匹配,例如<<_::size(4), @matched_string, _::binary>>,但您通常不能匹配任意子字符串。在这种情况下,您可以在;上拆分,修剪字符串,并检查它是否包含"x-wat"

def match(string) do
  string |> String.split(";") |> Enum.map(&String.trim/1) |> Enum.member?(string)
end

答案 1 :(得分:1)

你不能因为@Dogbert解释的原因,但有很多方法可以检查子串。

如果您没有约束,则可以执行

iex> "s-wat; x-wat" =~ "x-wat"
true

iex> String.contains? "s-wat; x-wat", "x-wat"
true

但是你有一些限制,所以你可以发挥创意。我将在现有答案的基础上添加另一个示例:

使用Regex

的一个示例
@matched_string "x-wat"

def match?(string) do
  ~r/^(.+; )?(#{@matched_string})(; [^\s]+)?$/ |> Regex.match?(string)
end

验证

iex(1)> import Regex
Regex

iex(2)> matched_string = "x-wat"
"x-wat"

iex(3)> r = ~r/^(.+; )?(#{matched_string})(; [^\s]+)?$/
~r/^(.+; )?(x-wat)(; [^\s]+)?$/

iex(4)> match?(r, "x-wat")
true

iex(5)> match?(r, "x-wat; s-wat")
true

iex(6)> match?(r, "s-wat; x-wat")
true

iex(7)> match?(r, "s-wat")
false

iex(8)> match?(r, "x-wat-y")
false