2014-09-17 7 views
14

Lets sagen, dass ich Match gegen Text mattern möchte. Genauer gesagt möchte ich eine Übereinstimmung mit dem ersten Buchstaben erzielen.Wie kann der Mustervergleich auf Text erfolgen?

Zum Beispiel, wie erstelle ich ein Muster, das "über" und "analog" aber nicht "Beta" zusammenpassen würde?

Ich habe dies versucht:

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

Ich habe auch versucht, Zeichenlisten:

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

Weder gearbeitet. Was ist der richtige Weg, um Text zu finden?

Antwort

25
defmodule MatchStick do 
    def doMatch("a" <> rest) do 1 end 
    def doMatch(_) do 0 end 
end 

Sie müssen die Zeichenfolge Verkettungsoperator here

Beispiel gesehen verwenden:

iex> "he" <> rest = "hello" 
"hello" 
iex> rest 
"llo" 
12

In Elixir, einzelne Strings in Anführungszeichen sind ganz verschieden von Doppelsaiten zitiert. Einzelne Anführungszeichenfolgen sind im Grunde Listen von Ganzzahlen, wobei jede Ganzzahl ein Zeichen darstellt. Daher werden sie auch Zeichenlisten genannt. Sie werden hauptsächlich für die Kompatibilität mit Erlang verwendet, da so Erlang-Saiten funktionieren. Sie können nur einzelne Strings in Anführungszeichen verwenden, wie Sie Listen verwenden würden:

iex> hd('a') 
97 

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

iex> 'ab' ++ rest = 'abcd' 
'abcd' 
iex> rest 
'cd' 

Die Match-Funktion für einzelne Strings in Anführungszeichen wie folgt aussehen würde:

def match('a' ++ rest), do: 1 
def match(_), do: 0 

Elixir wird die Liste auszublenden, von Ihnen und zeigt sie als eine Zeichenfolge, wenn alle Ganzzahlen gültige Zeichen darstellen. Dazu verleiten, Elixir Sie die interne Darstellung einer Zeichenliste angezeigt, können Sie ein 0, einfügen, die ein ungültiges Zeichen ist:

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

Allerdings würde man in der Regel verwenden Sie doppelte Anführungszeichen in Elixir, weil dieser Griff UTF- 8 richtig, sind viel einfacher zu arbeiten und werden von allen internen Elixir-Module (zum Beispiel die nützliche String Modul) verwendet. Doppel Strings in Anführungszeichen sind Binärdateien, so können Sie sie wie jede andere binäre Art behandeln:

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" 

Die Match-Funktion für doppelte Anführungszeichen würde wie folgt aussehen:

def match("a" <> rest), do: 1 
def match(_), do: 0 

Elixir wird verstecken die interne Darstellung von binäre Zeichenfolgen auch. Offenbaren sie, können Sie wieder legen Sie eine 0:

iex> string = "abcd" 
"abcd" 
iex> string <> <<0>> 
<<97, 98, 99, 100, 0>> 

Schließlich zwischen einzelnen Strings in Anführungszeichen und doppelte Anführungszeichen konvertieren können Sie die Funktionen nutzen to_string und to_char_list:

iex> to_string('abcd') 
"abcd" 
iex> to_char_list("abcd") 
'abcd' 

sie zu erkennen, Sie können is_list und is_binary verwenden. Diese arbeiten auch in Wächterklauseln.

iex> is_list('abcd') 
true 
iex> is_binary('abcd') 
false 
iex> is_list("abcd") 
false 
iex> is_binary("abcd") 
true 

Zum Beispiel die doppelten Anführungszeichen Version kompatibel mit einzelnen Strings in Anführungszeichen zu machen:

def match(str) when is_list(str), do: match(to_string(str)) 
def match("a" <> rest), do: 1 
def match(_), do: 0 
+0

Ich habe eine Frage zu dieser Codezeile: "iex> [97 | rest] = 'abcd'" Ich verstehe, warum es funktioniert, aber es ist nicht sehr lesbar. Gibt es eine Möglichkeit, etwas Ähnliches wie "iex> ['a' | rest] = 'abcd'" zu tun? – epotter

+0

Deshalb habe ich ein Beispiel mit dem Listenverkettungsoperator '++' hinzugefügt. Alternativ in binäre Zeichenfolge konvertieren :-) –

+1

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

0

Wenn Sie Muster auf dem Kopf eines charlist Spiel zu wollen, gibt es einen kleinen Unterschied Sie machen müssen in Ihrem zweiten Code-Snippet.

'a' ist eigentlich eine charlist mit einem Element, daher wird der Vergleich mit dem Kopf einer Charlist immer falsch sein. Ein charlist ist wirklich eine Liste von Integer-Wert:

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

Die char a entspricht 97 auf Integer. Sie können die Integer-Code eines Zeichens in Elixir erhalten, indem es mit einem ? vorhergehenden, so:

iex> ?a == 97 
true 
iex> ?a == hd('a') 
true 

So in der Hut-Klausel Sie head == ?a übereinstimmen soll, oder einfacher:

defmodule MatchStick do 
    def doMatch([?a | _tail]), do: 1 
    def doMatch(_), do: 0 
end