テキストに対してパターンマッチングを実行するとします。具体的には、最初の文字のパターンマッチングを行います。
たとえば、「about」と「analog」に一致するが「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');
どちらもうまくいきませんでした。テキストを一致させる適切な方法は何ですか?
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"
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
エリクサーは、バイナリ文字列の内部表現も非表示にします。それを明らかにするために、もう一度0
を挿入できます。
iex> string = "abcd"
"abcd"
iex> string <> <<0>>
<<97, 98, 99, 100, 0>>
最後に、単一引用符付き文字列と二重引用符付き文字列の間で変換するには、関数to_string
およびto_charlist
を使用できます。
iex> to_string('abcd')
"abcd"
iex> to_charlist("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
誰かが必要な場合に備えて。既知の中間にある文字列の一部を照合する必要があり、その長さがわかっている場合は、バイナリ照合を使用できます。
iex(1)> <<"https://", locale::binary-size(2), ".wikipedia.com" >> = "https://en.wikipedia.com"
"https://en.wikipedia.com"
iex(2)> locale
"en"
文字リストの先頭でパターンマッチングを行う場合、2番目のコードスニペットで行う必要があるわずかな違いが1つあります。
'a'
は実際には1つの要素を持つ文字リストであるため、文字リストの先頭との比較は常にfalseになります。 charlistは実際には整数値のリストです:
iex> 'abcd' == [97, 98, 99, 100]
true
Char a
は整数97
と同じです。 Elixirで文字の整数コードを取得するには、その前に?
を付けます。
iex> ?a == 97
true
iex> ?a == hd('a')
true
したがって、guard句では、head == ?a
またはより単純に一致させる必要があります。
defmodule MatchStick do
def doMatch([?a | _tail]), do: 1
def doMatch(_), do: 0
end