如何在文本上进行模式匹配?

epo*_*ter 23 elixir

让我们说我想模式匹配文本.具体来说,我想在第一个字母上模式匹配.

例如,如何创建一个匹配"约"和"模拟"但不匹配"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");
Run Code Online (Sandbox Code Playgroud)

我也尝试过角色列表:

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');
Run Code Online (Sandbox Code Playgroud)

都没有奏效.匹配文本的正确方法是什么?

Kyl*_*yle 33

defmodule MatchStick do
  def doMatch("a" <> rest) do 1 end
  def doMatch(_) do 0 end
end
Run Code Online (Sandbox Code Playgroud)

您需要使用此处显示的字符串连接运算符

例:

iex> "he" <> rest = "hello"
"hello"
iex> rest
"llo"
Run Code Online (Sandbox Code Playgroud)


Pat*_*ity 17

在Elixir中,单引号字符串与双引号字符串完全不同.单引号字符串基本上是整数列表,其中每个整数表示一个字符.因此,它们也被称为字符列表.它们主要用于与Erlang的兼容性,因为这是Erlang字符串的工作方式.您可以像使用列表一样使用单引号字符串:

iex> hd('a')
97

iex> [97 | rest] = 'abcd'
'abcd'
iex> rest
'bcd'

iex> 'ab' ++ rest = 'abcd'
'abcd'
iex> rest
'cd'
Run Code Online (Sandbox Code Playgroud)

单引号字符串的匹配函数如下所示:

def match('a' ++ rest), do: 1
def match(_), do: 0
Run Code Online (Sandbox Code Playgroud)

当所有整数代表有效字符时,Elixir将隐藏列表并将其显示为字符串.要欺骗Elixir向您显示字符列表的内部表示,您可以插入一个0无效字符:

iex> string = 'abcd'
'abcd'
iex> string ++ [0]
[97, 98, 99, 100, 0]
Run Code Online (Sandbox Code Playgroud)

但是,人们通常会在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"
Run Code Online (Sandbox Code Playgroud)

双引号字符串的匹配函数如下所示:

def match("a" <> rest), do: 1
def match(_), do: 0
Run Code Online (Sandbox Code Playgroud)

Elixir也会隐藏二进制字符串的内部表示.要显示它,您可以再次插入0:

iex> string = "abcd"
"abcd"
iex> string <> <<0>>
<<97, 98, 99, 100, 0>>
Run Code Online (Sandbox Code Playgroud)

最后,单引号字符串和双引号的字符串您可以使用功能之间的转换to_stringto_charlist:

iex> to_string('abcd')
"abcd"
iex> to_charlist("abcd")
'abcd'
Run Code Online (Sandbox Code Playgroud)

要检测它们,您可以使用is_listis_binary.这些也适用于保护条款.

iex> is_list('abcd')
true
iex> is_binary('abcd')
false
iex> is_list("abcd")
false
iex> is_binary("abcd")
true
Run Code Online (Sandbox Code Playgroud)

例如,要使双引号版本与单引号字符串兼容:

def match(str) when is_list(str), do: match(to_string(str))
def match("a" <> rest), do: 1
def match(_), do: 0
Run Code Online (Sandbox Code Playgroud)


Rud*_*chi 6

以防万一有人需要。如果您需要匹配已知中间的字符串部分并且您知道它的长度,那么您可以使用二进制匹配:

iex(1)> <<"https://", locale::binary-size(2), ".wikipedia.com" >> = "https://en.wikipedia.com" 
"https://en.wikipedia.com"
iex(2)> locale
"en"
Run Code Online (Sandbox Code Playgroud)