我现在正在写hg(mercurial)的客户端。对于tags命令,响应如下:
<<“添加\ na \ n提交的变更集 0:44108598f0ec643e7d90e9f18a2b6740401a510a \ n提示
1:ce4daf41b6ae \ nmy标签
0:44108598f0ec \ ntest tag 0:44108598f0ec 本地\ 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).
答案 0 :(得分: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
表达式
答案 1 :(得分: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)......