2012-12-07 60 views
1

我現在正在寫hg(mercurial)的客戶端。對於標記的命令,該效應初探如下:列表匹配(最後N個字符匹配)

< <「添加\ NA \ ncommitted變更 0:44108598f0ec643e7d90e9f18a2b6740401a510a \ n提示
1:ce4daf41b6ae \ n我的標籤
0:44108598f0ec \ NTEST標籤0: 44108598f0ec local \ n「>>。

蟒蛇的相關代碼如下:

t = [] 
    for line in out.splitlines(): 
     taglocal = line.endswith(' local') 
     if taglocal: 
      line = line[:-6] 
     name, rev = line.rsplit(' ', 1) 
     rev, node = rev.split(':') 
     t.append((name.rstrip(), int(rev), node, taglocal)) 
    return t 

我要檢查「本地」後綴everyline,但是編譯器會給出語法錯誤。如何正確書寫和優雅。 錯誤消息:

src/emercurial_client.erl:763: illegal pattern 

代碼

process_tags(List)-> 
    process_tags(List,[]). 

process_tags([],Result)-> 
    lists:reverse(Result); 

process_tags([Line|Rest],Result) -> 
    B = binary_to_list(Line), 
    A = process_tags_line(B), 
    process_tags(Rest,[A|Result]). 

process_tags_line(New_list ++"local")-> %%<-----error here 
process_tags_line(New_list); 

process_tags_line(New_list)-> 
    %% case List of 
    %%  Data ++ " local" -> %%<-----also match error 
    %%   New_list = Data; 
    %%  _ -> 
    %%   New_list = List 
    %% end, 
    [Name,Part2] = string:tokens(Data," "), 
    [Rev,Node] = string:tokens(Part2,":"), 
    {trim(Name),love_misc:to_integer(Rev), 
    node,New_list}. 

修改後,這是如下:

process_tags(List)-> 
    List_b = binary:split(List,<<$\n>>,[global]), 
    Result = process_tags(List_b,[]), 
    %% error_logger:info_report([client_process_tags,Result]), 
    Result. 

process_tags([],Result)-> 
    lists:reverse(Result); 

process_tags([<<>>],Result)-> 
    lists:reverse(Result); 

process_tags([Line|Rest],Result) -> 
    B = binary_to_list(Line), 
    A = process_tags_line(B), 
    process_tags(Rest,[A|Result]). 

process_tags_line(List) -> 
    %% error_logger:info_report([client_tags_line_1,List]), 
    case lists:suffix(" local",List) of 
     true -> 
      New_list = lists:sublist(List,1,length(List)-7); 
     _ -> 
      New_list = List 
    end, 
    {Name,Part2} = rsplit(New_list,$\s), 
    {Rev,Node} = 
     rsplit(Part2,$:), 
    Rev_a = string:substr(Rev,1,length(Rev)-1), 
    {love_misc:trim(Name),love_misc:to_integer(Rev_a),Node,New_list}. 

rsplit(A,Char)-> 
    Index = string:rchr(A,Char), 
    lists:split(Index,A). 

回答

3

如文檔指出,你可以match only prefixes in similar way(實際上它只是一個語法糖)。

我建議你使用功能lists:suffix

所以,你可以重寫代碼以這樣一種方式:

New_list = 
    case lists:suffix(" local", List) of 
     true -> 
      Data; 
     false -> 
      List 
    end 

注意,那case表達返回值,這樣你就可以綁定變量New_List只有一次 - 與結果case表達式,而不是綁定在每個分支的case表達式

2

我想你不能用這個模式匹配,因爲列表的底層結構( [A | [B | [.... | [] ...]])。

反向工程,以便你可以這樣做

process_tags_line(List) -> 
    process_tags_line_1(lists:reverse(List)). 
process_tags_line1(" lacol"++L) -> process_tags_line1(L); 
process_tags_line1(L) -> 
    New_list = lists:reverse(L), 
    [Name,Part2] = string:tokens(Data," "), 
    [Rev,Node] = string:tokens(Part2,":"), 
    {trim(Name),love_misc:to_integer(Rev),node,New_list}. 

但最簡單的事情可能是使用列表:後綴(L1,L2)...