1

我现在正在写 hg(mercurial) 的客户。对于标签命令,响应如下:

<<"添加一个\na\n提交的变更集 0:44108598f0ec643e7d90e9f18a2b6740401a510a\ntip
1:ce4daf41b6ae\nmy tags
0:44108598f0ec\ntest tag 0:44108598f0ec local\n">>.

python的相关代码如下:

    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

我必须检查每一行是否有“本地”后缀,但编译器会给出语法错误。如何正确和优雅地写作。错误信息:

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).
4

2 回答 2

3

正如文档中所指出的,您只能以类似的方式匹配前缀(实际上只是一种语法糖)。

我建议你使用功能lists:suffix

因此,您可以通过以下方式重写代码:

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

请注意,case表达式返回值,因此您只能绑定变量New_List一次 - 使用表达式的结果,而不是在表达式case的每个分支中绑定case

于 2012-12-07T10:35:35.143 回答
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}.

但最简单的可能是使用列表:suffix(L1,L2)...

于 2012-12-07T08:36:57.380 回答