【问题标题】:How can i split a binary in erlang如何在erlang中拆分二进制文件
【发布时间】:2010-09-30 11:57:20
【问题描述】:

我想,我想要的比较简单:

> Bin = <<"Hello.world.howdy?">>.
> split(Bin, ".").
[<<"Hello">>, <<"world">>, <<"howdy?">>]

任何指针?

【问题讨论】:

    标签: erlang binary


    【解决方案1】:

    在 R12B 中,二进制拆分的速度大约提高了 15%:

    split2(Bin, Chars) ->
        split2(Chars, Bin, 0, []).
    
    split2(Chars, Bin, Idx, Acc) ->
        case Bin of
            <<This:Idx/binary, Char, Tail/binary>> ->
                case lists:member(Char, Chars) of
                    false ->
                        split2(Chars, Bin, Idx+1, Acc);
                    true ->
                        split2(Chars, Tail, 0, [This|Acc])
                end;
            <<This:Idx/binary>> ->
                lists:reverse(Acc, [This])
        end.
    

    如果您使用的是 R11B 或更早版本,请改用 archaelus version。

    上面的代码在 std 上更快。只有 BEAM 字节码,在 HiPE 中没有,两者几乎相同。

    编辑:请注意此代码已被新模块 binary 自 R14B 起废弃。请改用binary:split(Bin, &lt;&lt;"."&gt;&gt;, [global]).。

    【讨论】:

      【解决方案2】:
      binary:split(Bin,<<".">>).
      

      【讨论】:

      • 这只会拆分第一项,因此返回值将是 [>,>]。解决方案是传递全局选项:binary:split(Bin,>, [global]).
      【解决方案3】:

      来自EEP31(和EEP9)的模块binary被添加到Erts-5.8(参见OTP-8217):

      1> Bin = <<"Hello.world.howdy?">>.
      <<"Hello.world.howdy?">>
      2> binary:split(Bin, <<".">>, [global]).
      [<<"Hello">>,<<"world">>,<<"howdy?">>]
      

      【讨论】:

        【解决方案4】:

        当前没有与lists:split/2 等效的 OTP 函数可用于二进制字符串。在EEP-9 公开之前,您可以编写一个二进制拆分函数,如:

        split(Binary, Chars) ->
            split(Binary, Chars, 0, 0, []).
        
        split(Bin, Chars, Idx, LastSplit, Acc)
          when is_integer(Idx), is_integer(LastSplit) ->
            Len = (Idx - LastSplit),
            case Bin of
                <<_:LastSplit/binary,
                 This:Len/binary,
                 Char,
                 _/binary>> ->
                    case lists:member(Char, Chars) of
                        false ->
                            split(Bin, Chars, Idx+1, LastSplit, Acc);
                        true ->
                            split(Bin, Chars, Idx+1, Idx+1, [This | Acc])
                    end;
                <<_:LastSplit/binary,
                 This:Len/binary>> ->
                    lists:reverse([This | Acc]);
                _ ->
                    lists:reverse(Acc)
            end.
        

        【讨论】:

          【解决方案5】:

          这是一种方法:

          re:split(<<"Hello.world.howdy?">>, "\\.").
          

          【讨论】:

            猜你喜欢
            • 2015-06-01
            • 1970-01-01
            • 2015-06-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-10
            相关资源
            最近更新 更多