如何在Erlang中拆分二进制?

10
我想要的东西,我认为相对简单:
> Bin = <<"Hello.world.howdy?">>.
> split(Bin, ".").
[<<"Hello">>, <<"world">>, <<"howdy?">>]

有什么指针吗?

5个回答

20
binary:split(Bin,<<".">>).

4
这只会分割第一个项目,因此返回值将是[<<Hello>>,<<World.Howdy?>>]。解决方法是传递全局选项: binary:split(Bin, <<".">>, [global])。 - Myles McDonnell

10

EEP31(和EEP9)中引入的binary模块已添加在Erts-5.8中(请参考OTP-8217):

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

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.

如果您使用的是R11B或更早版本,请改用archaelus version
上述代码仅在std. BEAM字节码上更快,而不是在HiPE上,两者几乎相同。
编辑:请注意,此代码已被新模块binary所取代,自R14B起已过时。请改用binary:split(Bin, <<".">>, [global])

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.

3
这里有一种方法:
re:split(<<"Hello.world.howdy?">>, "\\.").

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接