2012-12-07 43 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)...