【问题标题】:Split Erlang UTF8 binary by characters按字符拆分 Erlang UTF8 二进制文件
【发布时间】:2015-06-10 22:14:03
【问题描述】:

如何拆分二进制 Erlang 字符串,将其数据视为 UTF8 字符?

假设我们有一个二进制文件,它应该被分成两部分,第一部分应该包含前两个 UTF8 字符。下面是几个例子:
<<"ąčęė">> 应该变成[<<"ąč">>, <<"ęė">>]

<<"あぁぅうぁ">> 应该变成[<<"あぁ">>, <<"ぅうぁ">>]

【问题讨论】:

  • 对不起,我不明白你想得到什么结果?
  • 我正在寻找一种基于字符数而不是字节数来拆分二进制 UTF8 字符串的方法。

标签: string utf-8 binary erlang


【解决方案1】:

不过,我还不清楚,但我认为这会成功:

Eshell V6.2  (abort with ^G)          
1> Input = <<"ąčęė">>.                
<<"ąčęė">>                            
2> L = [X || <<X:2/binary>> <= Input].
[<<"ąč">>,<<"ęė">>]                   
3>


更新:这个会拆分成S, TheRest:

%% S is the number of characters you want
split_it(S, Bin) when S > 0 ->
  case Bin of
    <<P:S/binary, R/binary>> -> [P | split_it(infinity, R)];
    <<>> -> [];
    _ -> [Bin]
  end.           

【讨论】:

  • 我的意思是数据应该按字符索引,而不是字节或位。恐怕您的 sn-p 不适用于长度不均匀的字符串,而且结果应该由二进制而不是位串组成。
  • @cnduo 你应该更清楚地提出问题。结果显示你想看。可以把上面的代码2换成1,得到:[>,>,>,>]
  • 请查看我的最新编辑。删除了可能冗余和误导性的信息。
【解决方案2】:

要将一个 utf-8 编码的二进制字符串分成两部分,第一部分包含前两个字符,第二部分包含其余部分,您可以使用该函数:

split_2(<<One/utf8,Two/utf8,Rest/binary>>) ->
    %% One and Two are now the unicode codepoints of the first 2 characters.
    [<<One/utf8,Two/utf8>>,Rest].

匹配带有 utf8 的二进制文件将提取第一个 utf-8 编码字符并将 unicode 代码点作为整数返回,这就是为什么我们必须构建前两个字符的结果二进制文件的原因。如果二进制文件中的第一个不是 2 个 utf-8 编码字符,则此函数将失败。

位串和二进制的区别在于二进制的大小必须是 8 位的倍数,而位串可以是任意大小。

【讨论】:

  • 感谢您的回复。分割任意数量的字符怎么样?
  • @cnduo 恐怕你得用递归函数,一个一个地提取字符,因为你看不到有多少字节对应你的字符数,换句话说,你必须解析所有utf8 字符
  • 是的,正如@kitty 所说。您只能从二进制文件的前面显式提取字符,这里我取 2,所以如果您想要一个任意数字,那么您需要在二进制文件上递归。
【解决方案3】:

恰好需要这样的功能。这就是我最终的结果:

trunc_utf8(Utf8s, Count) ->
    trunc_utf8(Utf8s, Count, <<>>).
trunc_utf8(<<>>, _Count, Acc) -> Acc;
trunc_utf8(_Utf8s, 0, Acc) -> Acc;
trunc_utf8(<<H/utf8, T/binary>> = _Utf8s, Count, Acc) ->
    trunc_utf8(T, Count - 1, <<Acc/binary, H/utf8>>).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-01
    • 2010-09-30
    • 2014-08-10
    • 1970-01-01
    • 2015-05-26
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多