2014-09-17 2 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 

비약 당신의 목록을 숨길하고로 표시 모든 정수가 유효한 문자를 나타낼 때 문자열. 당신에게 문자 목록의 내부 표현을 보여주는에 비약을 속여하려면 잘못된 문자 인 0, 삽입 할 수 있습니다 : 하나는 일반적으로, 엘릭서 이중 인용 문자열을 사용합니다, 그러나

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

이 핸들 UTF-때문에 8을 사용하면 훨씬 쉽게 작업 할 수 있으며 모든 내부 엘 릭크 모듈 (예 : 유용한 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 

비약이의 내부 표현을 숨 깁니다 바이너리 문자열. 이 기능 to_stringto_char_list 사용할 수 있습니다 인용 한 문자열을 두 번 인용 문자열 사이의 변환,

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

마지막 :를 표시하려면, 당신은 다시 0를 삽입 할 수 있습니다

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

그들을 발견하기를, is_listis_binary을 사용할 수 있습니다. 이들은 또한 가드 절에서 작동합니다.

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

예를 들어, 하나의 인용 문자열 이중 인용 버전이 호환되도록 : 당신이 charlist의 머리에 패턴 일치를 원하는 경우

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 | 나머지] = 'abcd'"왜 작동하는지 이해하지만 읽는 것은 쉽지 않습니다. 이 "iex> [ 'a'| rest] = 'abcd'"와 비슷한 것을 할 수있는 방법이 있습니까? – epotter

+0

그 이유는 목록 연결 연산자'++'로 예제를 추가했기 때문입니다. 또는 이진 문자열로 변환 : –

+1

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

0

, 당신이해야 하나 개 약간의 차이가있다 두 번째 코드 스 니펫에

'a'은 실제로 하나의 요소가있는 charlist이므로 charlist의 머리글과 비교하면 항상 false입니다. charlist 정말 정수 값의 목록입니다

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

a97을 정수로 동일시한다. 단순히 더 가드 절에 따라서

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 
관련 문제