我如何在erlang中拆分二进制文件

Hal*_*dun 9 binary erlang

我想,我想要的是相对简单的:

> Bin = <<"Hello.world.howdy?">>.
> split(Bin, ".").
[<<"Hello">>, <<"world">>, <<"howdy?">>]
Run Code Online (Sandbox Code Playgroud)

有什么指针吗?

小智 19

binary:split(Bin,<<".">>).
Run Code Online (Sandbox Code Playgroud)

  • 这只会拆分第一项,所以返回值为[<< Hello >>,<< World.Howdy?>>].解决方案是传递全局选项:binary:split(Bin,<<".">>,[global]). (4认同)

hdi*_*ima 9

该模块二进制EEP31(和EEP9中的溶液中加入)厄茨-5.8(见OTP-8217):

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


Hyn*_*dil 5

在 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.
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:请注意此代码自 R14B 以来已被新模块二进制文件废弃。使用binary:split(Bin, <<".">>, [global]).来代替。


arc*_*lus 4

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

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.
Run Code Online (Sandbox Code Playgroud)