让我们说我希望模式匹配文本。具体来说,我想在第一个字母上进行模式匹配。
例如,如何创建一个匹配" about"和"模拟"但不是" beta"?
我试过这个:
defmodule MatchStick do
def doMatch([head | tail]) when head == "a" do 1 end
def doMatch([head | tail]) do 0 end
end
res = MatchStick.doMatch("abcd");
我还尝试了角色列表:
defmodule MatchStick do
def doMatch([head | tail]) when head == 'a' do 1 end
def doMatch([head | tail]) do 0 end
end
res = MatchStick.doMatch('abcd');
都没有奏效。匹配文本的正确方法是什么?
答案 0 :(得分:32)
defmodule MatchStick do
def doMatch("a" <> rest) do 1 end
def doMatch(_) do 0 end
end
您需要使用字符串连接运算符here
示例:
iex> "he" <> rest = "hello"
"hello"
iex> rest
"llo"
答案 1 :(得分:16)
在Elixir中,单引号字符串与双引号字符串完全不同。单引号字符串基本上是整数列表,其中每个整数表示一个字符。因此,它们也被称为字符列表。它们主要用于与Erlang兼容,因为它是Erlang字符串的工作方式。您可以像使用列表一样使用单引号字符串:
iex> hd('a')
97
iex> [97 | rest] = 'abcd'
'abcd'
iex> rest
'bcd'
iex> 'ab' ++ rest = 'abcd'
'abcd'
iex> rest
'cd'
单引号字符串的匹配函数如下所示:
def match('a' ++ rest), do: 1
def match(_), do: 0
当所有整数代表有效字符时,Elixir将隐藏您的列表并将其显示为字符串。要欺骗Elixir向您显示字符列表的内部表示,您可以插入0
,这是一个无效字符:
iex> string = 'abcd'
'abcd'
iex> string ++ [0]
[97, 98, 99, 100, 0]
但是,人们通常会在Elixir中使用双引号字符串,因为它们正确处理UTF-8,更易于使用并且被所有内部Elixir模块使用(例如有用的String
模块)。双引号字符串是二进制文件,因此您可以将它们视为任何其他二进制类型:
iex> <<97, 98, 99, 100>>
"abcd"
iex> <<1256 :: utf8>>
"Ө"
iex> <<97>> <> rest = "abcd"
"abcd"
iex> rest
"bcd"
iex> "ab" <> rest = "abcd"
"abcd"
iex> rest
"cd"
双引号字符串的匹配函数如下所示:
def match("a" <> rest), do: 1
def match(_), do: 0
Elixir也会隐藏二进制字符串的内部表示。要显示它,您可以再次插入0
:
iex> string = "abcd"
"abcd"
iex> string <> <<0>>
<<97, 98, 99, 100, 0>>
最后,要在单引号字符串和双引号字符串之间进行转换,您可以使用函数to_string
和to_char_list
:
iex> to_string('abcd')
"abcd"
iex> to_char_list("abcd")
'abcd'
要检测它们,您可以使用is_list
和is_binary
。这些也适用于保护条款。
iex> is_list('abcd')
true
iex> is_binary('abcd')
false
iex> is_list("abcd")
false
iex> is_binary("abcd")
true
例如,要使双引号版本与单引号字符串兼容:
def match(str) when is_list(str), do: match(to_string(str))
def match("a" <> rest), do: 1
def match(_), do: 0
答案 2 :(得分:0)
如果你想在一个charlist的头部进行模式匹配,你需要在你的第二个代码片段中略微区别。
'a'
实际上是一个包含一个元素的charlist,因此与charlist的头部进行比较将始终为false。 charlist实际上是一个整数值列表:
iex> 'abcd' == [97, 98, 99, 100]
true
char a
等于整数97
。您可以在Elixir中使用?
前面的字符获取字符的整数代码,所以:
iex> ?a == 97
true
iex> ?a == hd('a')
true
因此,在您的保护条款中,您需要匹配head == ?a
,或者更简单地匹配:
defmodule MatchStick do
def doMatch([?a | _tail]), do: 1
def doMatch(_), do: 0
end
答案 3 :(得分:0)
以防万一有人需要。如果您需要匹配已知中间部分的字符串,并且知道其长度,则可以使用二进制匹配:
iex(1)> <<"https://", locale::binary-size(2), ".wikipedia.com" >> = "https://en.wikipedia.com"
"https://en.wikipedia.com"
iex(2)> locale
"en"