2014-09-17 3 views
14

Допустим, что я хочу сопоставить шаблон с текстом. В частности, я хочу сопоставить шаблон по первой букве.Как выполнить сопоставление образцов по тексту?

Например, как создать шаблон, который будет соответствовать «около» и «аналог», но не «бета»?

Я попытался это:

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'); 

Ни работал. Каков правильный способ соответствия текста?

ответ

25
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" 
12

В эликсира, одиночные строки в кавычках сильно отличаются от строк в двойных кавычках. Одиночные кавычки - это в основном списки целых чисел, где каждое целое число представляет символ. Поэтому они также называются списками символов. Они в основном используются для совместимости с 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 будет скрыть список от вас и отображать его как строка, когда все целые числа представляют действительные символы. Для того, чтобы обмануть эликсира в показывая внутреннее представление списка символов, вы можете вставить 0, что это неверный символ:

iex> string = 'abcd' 
'abcd' 
iex> string ++ [0] 
[97, 98, 99, 100, 0] 

Однако, один, как правило, использовать двойные кавычки строки в эликсира, потому что эти ручки 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 
+0

У меня есть вопрос об этой строке кода: "iex> [97 | rest] = 'abcd'" Я понимаю, почему это работает, но это не очень читаемо. Есть ли способ сделать что-то подобное этому "iex> ['a' | rest] = 'abcd'? – epotter

+0

Вот почему я добавил пример с оператором конкатенации списка '++'. Альтернативно конвертировать в двоичную строку :-) –

+1

@epotter: '[? A | rest] = 'abcd'' – Kabie

0

Если вы хотите, чтобы шаблон матч на головке charlist, есть одна небольшая разница вам нужно сделать в вашем втором фрагменте кода.

'a' на самом деле является charlist с одним элементом, поэтому сравнение с головой charlist всегда будет ложным. Charlist действительно список целочисленных значений:

iex> 'abcd' == [97, 98, 99, 100] 
true 

полукокса a приравнивает к целому 97. Вы можете получить целочисленный код символа в эликсира, предварив его с ?, так:

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 

 Смежные вопросы

  • Нет связанных вопросов^_^