erlang string -> term,term->string

如果不是用日志,我当前知道的erlang term-> string 的方式就是 io_lib:format,例如:

A = io_lib:format("~p~p",["123",["321",123,123,{123,123}]]).
["\"123\"",
 [91,
  ["\"321\"",44,"123",44,"123",44,[123,["123",44,"123"],125]],
  93]]
6> io:format("~ts", [A]).
"123"["321",123,123,{123,123}]ok
还有一个比较笨的方法是如下:any_to_list 做 ++ 处理,然后输出

string -> erlang term 的方式是如下的函数 to_params_term/1,参数是string类型的 erlang term, 函数原型如下:

     1> {ok,Tokens,_} = erl_scan:string("[{foo,bar},x,3].").
        {ok,[{'[',1}, {'{',1}, {atom,1,foo}, {',',1}, {atom,1,bar},...
     2> {ok,Term} = erl_parse:parse_term(Tokens).
        {ok,[{foo,bar},x,3]}
        

一些测试代码:

-module(test).
-compile(export_all).

any_to_list(undefined) ->
    "";
any_to_list(List) when is_list(List) ->
    List;
any_to_list(Bin) when is_binary(Bin) ->
    case unicode:characters_to_binary(Bin, utf8, utf8) of
        Bin -> unicode:characters_to_list(Bin);
        _ -> binary_to_list(Bin)
    end;
any_to_list(Atom) when is_atom(Atom) ->
    atom_to_list(Atom);
any_to_list(Number) when is_integer(Number) ->
    integer_to_list(Number);
any_to_list(Float) when is_float(Float) ->
    float_to_list(Float, [{decimals, 4},compact]);
any_to_list(Tuple) when is_tuple(Tuple) ->
    tuple_to_list(Tuple);
any_to_list(_) ->
    throw(badarg).

to_string(ListTerm)  when is_list(ListTerm) ->
    to_string(ListTerm,"");
to_string(Term)  ->
    to_string(any_to_list(Term)).  

to_string([], R) -> 
    lists:reverse(R);
to_string([H|T], R) ->
    Tile = ["\n"| R],
    to_string(T, [any_to_list(H) | Tile]);
to_string(_, _)  ->
    {error,error_type}.

%%当有深层次的嵌套时候就会把前面的字符串显示成数字,不知道怎么解决
any_to_a_string(Term) -> 
    ListTest = any_to_list(Term),
    case ListTest of
        ListTest when is_list(ListTest) ->
         StringWithOddColon = 
            lists:foldl(fun(Number, Acc) ->
                            Acc ++ any_to_list(Number) ++ ","
                        end, "", ListTest) ,
            lists:droplast(StringWithOddColon);
        _ ->
           {error,error_type} 
    end.

any_to_individual_string(Term) -> 
    ListTest = any_to_list(Term),
    case ListTest of
        ListTest when is_list(ListTest) ->
        [_H | ReversedString] =
            lists:foldl(fun(Number, Acc) ->
                            [any_to_list(Number) | Acc]
                        end, "", ListTest) ,
            lists:reverse(ReversedString);
        _ ->
            any_to_list(ListTest)
    end.


to_params_term(String) ->
    case erl_scan:string(lists:append(String, ".")) of
        {ok, ScannedString, _ } ->
            case  erl_parse:parse_exprs(ScannedString) of 
                {ok, ParsedString} ->
                    {value, Term, []} = erl_eval:exprs(ParsedString, []),
                    Term;
                {error, Reason} ->
                    {error, Reason}
            end;
        {error, Reason, _} ->
            {error, Reason}
    end.

测试:

39> c(test).
{ok,test}
40> test:to_string([<<"abc123">>,123,53,67.54363,{<<"abc">>, <<"a12">>}]).
["\n","abc123","\n","123","\n","53","\n","67.5436","\n",
 [<<"abc">>,<<"a12">>]]
41> test:any_to_a_string([<<"abc123">>,123,53,67.54363,{<<"abc">>, <<"a12">>}]).
[97,98,99,49,50,51,44,49,50,51,44,53,51,44,54,55,46,53,52,
 51,54,44,<<"abc">>,<<"a12">>]
42> test:any_to_a_string([<<"abc123">>,123,53,67.54363,<<"abc">>, <<"a12">>]).  
"abc123,123,53,67.5436,abc,a12"
43> test:any_to_individual_string([<<"abc123">>,123,53,67.54363,<<"abc">>, <<"a12">>]).
["abc123","123","53","67.5436","abc"]
44> test:to_params_term("["abc123","123","53","67.5436","abc"]").
 1: syntax error before: abc123
44> test:to_params_term("[abc123,123,53,67.5436,abc]").           
[abc123,123,53,67.5436,abc]

参考资料:
坚强2002的博客 From String To Erlang Code
坚强2002的博客string To Erlang Term 一个更为考虑更为完善的方法,此处说的更详细
[erlang类型转换](http://www.cnblogs.com/ShankYan/p/4141803.html)

posted @ 2015-01-04 22:18  ShankYan  阅读(1178)  评论(0编辑  收藏  举报