对于我的应用程序,我必须使用Erlang解析CSV文件.以下是使用Erlang解析CSV的代码: -
parse_file(Fn) ->
{ok, Data} = file:read_file(Fn),
parse(binary_to_list(Data)).
parse(Data) -> lists:reverse(parse(Data, [])).
parse([], Acc) -> Acc;
parse(Data, Acc) ->
{Line, Tail} = parse_line(Data),
parse(Tail, [Line|Acc]).
parse_line(Data) ->
{Line, Tail} = parse_line(Data, []),
{lists:reverse(Line), Tail}.
parse_line([13,10|Data], Acc) -> {Acc, Data};
parse_line([10|Data], Acc) -> {Acc, Data};
parse_line([13|Data], Acc) -> {Acc, Data};
parse_line([], Acc) -> {Acc, []};
parse_line([$,,$,|Data], Acc) -> parse_line(Data, [""|Acc]);
parse_line([$,|Data], Acc) -> parse_line(Data, Acc);
parse_line(Data, Acc) ->
{Fld, Tail} = parse_field(Data),
parse_line(Tail, [Fld|Acc]).
parse_field([34|Data]) ->
{Fld, Tail} = parse_fieldq(Data, ""),
{lists:reverse(Fld), Tail};
parse_field(Data) ->
{Fld, Tail} = parse_field(Data, ""),
{lists:reverse(Fld), Tail}.
parse_field([$,|Tail], Acc) -> {Acc, [$,|Tail]};
parse_field([13|Tail], Acc) -> {Acc, [13|Tail]};
parse_field([10|Tail], Acc) -> {Acc, [10|Tail]};
parse_field([], Acc) -> {Acc, []};
parse_field([Ch|Tail], Acc) -> parse_field(Tail, [Ch|Acc]).
parse_fieldq([34,34|Tail], Acc) -> parse_fieldq(Tail, [34|Acc]);
parse_fieldq([34|Tail], Acc) -> {Acc, Tail};
parse_fieldq([Ch|Tail], Acc) -> parse_fieldq(Tail, [Ch|Acc]).
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常,但有两个问题: - 1 - 因为代码解析使用双引号("")和逗号(,)并分隔每个值..但在下面的示例中,如果名字首先包含双引号,那么解析器将创建另一个字段.
"Type","First Name","Last Name","Email"
"Contact","Ashwani Garg ------"All Pain Will End."","","itisashwani4u@gmail.com"
result:-
[["contact"],["Ashwani Garg ------"],["All Pain Will End."],[],["itisashwani4u@gmail.com"]]
expected result:-
[["contact"],["Ashwani Garg ------All Pain Will End."],[],["itisashwani4u@gmail.com"]]
Run Code Online (Sandbox Code Playgroud)
2 - 对于以下类型的csv它的值,它截断一些值: - 名字,姓氏,中间名,姓名,昵称,电子邮件地址,家庭街道,本地城市,家庭邮政编码,家庭状态,家庭国家/地区,家庭电话,家庭传真,移动电话,个人网页,商业街,商业城,商业邮政编码,商业状态,商业国家/地区,商业网页,商务电话,商业传真,寻呼机,公司,工作标题,部门,办公地点,备注
Affection,,,Affection,,,,,,,,+919845141544,,+919845141544,,,,,,,,,,,,,,,
result:-
[["Affection"],[],[],["Affection"],[],[],[],[],[],[],[],["+919845141544"],[],["+919845141544"],[],[],[],[],[],[],[]]
expected result:-
[["Affection"],[],[],["Affection"],[],[],[],[],[],[],[],["+919845141544"],[],["+919845141544"],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
Run Code Online (Sandbox Code Playgroud)
请帮助我...参考请使用以下链接: - http://ppolv.wordpress.com/2008/02/25/parsing-csv-in-erlang/
parse(File) ->
{ok, F} = file:open(File, [read, raw]),
parse(F, file:read_line(F), []).
parse(F, eof, Done) ->
file:close(F),
lists:reverse(Done);
parse(F, Line, Done) ->
parse(F, file:read_line(F), [parse_line(Line)|Done]).
parse_line(Line) -> parse_line(Line, []).
parse_line([], Fields) -> lists:reverse(Fields);
parse_line("," ++ Line, Fields) -> parse_field(Line, Fields);
parse_line(Line, Fields) -> parse_field(Line, Fields).
parse_field("\"" ++ Line, Fields) -> parse_field_q(Line, [], Fields);
parse_field(Line, Fields) -> parse_field(Line, [], Fields).
parse_field("," ++ _ = Line, Buf, Fields) -> parse_line(Line, [lists:reverse(Buf)|Fields]);
parse_field([C|Line], Buf, Fields) -> parse_field(Line, [C|Buf], Fields);
parse_field([], Buf, Fields) -> parse_line([], [lists:reverse(Buf)|Fields]).
parse_field_q(Line, Fields) -> parse_field_q(Line, [], Fields).
parse_field_q("\"\"" ++ Line, Buf, Fields) -> parse_field_q(Line, [$"|Buf], Fields);
parse_field_q("\"" ++ Line, Buf, Fields) -> parse_line(Line, [lists:reverse(Buf)|Fields]);
parse_field_q([C|Line], Buf, Fields) -> parse_field_q(Line, [C|Buf], Fields).
Run Code Online (Sandbox Code Playgroud)
没有文件:read_line:
parse_file(File) ->
{ok, Data} = file:read_file(File),
parse(binary_to_list(Data), []).
parse([], Done) ->
lists:reverse(Done);
parse(Data, Done) ->
{Line, Rest} = case re:split(Data, "\r|\n|\r\n", [{return, list}, {parts, 2}]) of
[L,R] -> {L,R};
[L] -> {L,[]}
end,
parse(Rest, [parse_line(Line)|Done]).
Run Code Online (Sandbox Code Playgroud)