【问题标题】:splitting of binaries二进制文件的拆分
【发布时间】:2012-06-16 06:43:20
【问题描述】:

我试图从一个二进制字符串中拆分两个字段:

-define(S,<<"M\0\0\0522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,‌​0110,00,150,0,0,0\0">>).<<Message_length:4/binary,Msg/binary>> = S.

前4个字节是后面消息的长度,其他字节是消息,
一个空字节终止字符串。

结果是: ** 异常错误:右侧值不匹配
编辑 就在给定代码之前,有:

[Sequence|Reste] = binary:split(T,<<"\0">>),

“休息”有界吗?

【问题讨论】:

    标签: erlang


    【解决方案1】:

    你的代码没问题,要么你没有二进制字符串,要么 Mystring 的长度不符合模式。这是一个快速测试:

    1> Mystring = <<"abcde">>.
    <<"abcde">>
    2> <<Message_length:4/binary,Msg/binary>> = Mystring.
    <<"abcde">>
    3> Message_length.
    <<"abcd">>
    4> Msg.
    <<"e">>
    

    如果你有一个字符串(整数列表)而不是二进制字符串(>),正如 Vincenzo 建议的那样,请先调用 erlang:list_to_binary/1。

    希望对你有帮助

    编辑:我已经检查了您在 Vincenzo 的回答的评论中留下的示例字符串。我已经用你的代码试过了,仍然有效。到达那行代码时,Message_length 和/或 Msg 是否可能已经绑定(并且与 Mystring 不同)?这将使模式匹配失败。

    EDIT2:使用问题中的更新数据进行测试:

    1> S = <<"M\0\0\0522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,\342\200\214\342\200\2130110,00,150,0,0,0\0">>.
    <<77,0,0,42,50,48,51,57,51,53,53,48,57,57,44,48,49,48,49,
      48,48,48,48,48,48,48,56,44,48,...>>
    2> <<Message_length:4/binary,Msg/binary>> = S.
    <<77,0,0,42,50,48,51,57,51,53,53,48,57,57,44,48,49,48,49,
      48,48,48,48,48,48,48,56,44,48,...>>
    3> Message_length.
    <<77,0,0,42>>
    4> Msg.
    <<"2039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,\342"...>>
    

    【讨论】:

    • 是的,现在知道字符串了,我同意你的观点,这应该是 Message_length 和 Msg 上的模式反弹错误。与您在 R15B01 上的结果相同(已测试)。
    • 77后有两个空值,S中三个空值!!?我不明白模式反弹的概念。
    • @Bertaud \OOO 实际上是在寻找 3 个数字,它们指定了一个 3 位八进制数。所以在这种情况下,你有八进制:0、0、052(十进制的 42)。模式反弹意味着您正在尝试将值重新分配给已绑定的变量,如果这些值不完全相同,这将导致您提到的错误
    • 我用 emacs 测试。在每次修改后我重新编译并运行代码。我的变量不应该反弹? M\0\0\0 为 4 字节长度:长度为 77 字节(77 = M)
    • Message_length 应该是 > 而不是 >
    【解决方案2】:

    erlang 字符串转义插值存在问题。第四个字节不是插入为"\0",而是"\052"。

    1> Bin = <<"M\0\0\0522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,0110,00,150,0,0,0\0">>.
    <<77,0,0,42,50,48,51,57,51,53,53,48,57,57,44,48,49,48,49,                                                                                                                     
      48,48,48,48,48,48,48,56,44,48,...>>
    

    所以你必须这样写。

    2> f().
    ok
    3> Bin = <<"M\0\0\0","522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,0110,00,150,0,0,0\0">>.
    <<77,0,0,0,53,50,50,48,51,57,51,53,53,48,57,57,44,48,49,
      48,49,48,48,48,48,48,48,48,56,...>>
    

    那么解析这种形式的消息的常用方法是:

    4> <<L:32/little,Rest/binary>> = Bin.
    <<77,0,0,0,53,50,50,48,51,57,51,53,53,48,57,57,44,48,49,
      48,49,48,48,48,48,48,48,48,56,...>>
    5> L.
    77
    6> <<Msg:L/binary,R/binary>> = Rest.
    <<"522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,0110,00,150,0,0,0"...>>
    7> R.
    <<0>>
    8> Msg.
    <<"522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,0110,00,150,0,0,0">>
    

    【讨论】:

      【解决方案3】:

      你必须在要匹配的字符串上调用list_to_binary/1。

      如果您还有其他问题,请输入示例字符串!

      【讨论】:

      • -define(S,>).
      • @Bertaud 这是 Mystring 的内容吗?你能用这个例子更新问题吗?
      猜你喜欢
      • 1970-01-01
      • 2015-05-26
      • 2010-09-30
      • 2015-06-10
      • 1970-01-01
      • 2015-06-01
      • 2011-05-24
      • 1970-01-01
      • 2015-05-05
      相关资源
      最近更新 更多