代码之家  ›  专栏  ›  技术社区  ›  Kirill kilo-code Babkin

无法使用Elixir中的二进制运算符提取部分字符串

  •  1
  • Kirill kilo-code Babkin  · 技术社区  · 7 年前

    您好,我正在尝试理解如何使用Elixir中的二进制文件,我正在尝试解析字符串

    "2018-04-07 13:00:00.000000"
    

    我想得到他们今年的部分,我做了以下工作

    date = "2018-04-07 13:00:00.000000"
    << d::size(80), rest::binary >> = date
    

    现在,当我尝试休息时,我会在约会后得到一切,包括空间

    " 13:00:00.000000"
    

    但是如果我想得到d,我真的不明白我得到了什么,但结果如下

    237007314493411930484791
    

    你们能帮我弄明白发生了什么事吗。

    非常感谢。

    2 回复  |  直到 7 年前
        1
  •  5
  •   Aleksei Matiushkin    7 年前

    虽然Kevin Johnson提供的答案完美地解释了如何处理二进制文件,但我将发布对实际情况的解释。

    Erlang中的二进制(因此Elixir中的二进制)可以使用字符的ASCII值创建:

    iex|1 ▶ <<50, 48>>
    #⇒ "20"
    

    当您的图案匹配到 size(80) 实际上,模式匹配到256基中整数的10个位置。基本上,情况就是这样:

    iex|2 ▶ <<a1::size(8), a2::size(8), a3::size(8),
              a4::size(8), a5::size(8), a6::size(8),
              a7::size(8), a8::size(8), a9::size(8),
              a10::size(8), _ :: binary>> = "2018-04-07 13..."
    #⇒ "2018-04-07 13..."
    

    让我们检查我们的值(是的,只要可能,整数数组都会打印为位字符串,注意 单引号 ):

    iex|3 ▶ [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10] 
    #⇒ '2018-04-07'
    

    好的,到目前为止还不错。现在让我们从上述整数中得到结果。这将是:

    a10 * 1 + a9 * 256 + a8 * 256² + ...
    

    或者,使用有限的长生不老药算术能力:

    iex|4 ▶ [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]
    ...|4 ▷ |> Enum.reverse
    ...|4 ▷ |> Enum.with_index
    ...|4 ▷ |> Enum.reduce(0, fn {e, i}, acc ->
    ...|4 ▷                     # ⇓⇓⇓ exact integer i-power of 256 ⇓⇓⇓
    ...|4 ▷      acc + e * Enum.reduce(List.duplicate(256, i), 1, &Kernel.*/2)
    ...|4 ▷ end)
    #⇒ 237007314493411930484791
    

    这正是您在要求将前10个位置与基于256的10位数进行模式匹配时得到的结果。

        2
  •  4
  •   Kevin Johnson    7 年前

    解决问题的方法是使用 binary-size 具体如下: << d::binary-size(10), rest::binary >> = date

    以下是 documentation 应相应澄清:

    一个位字符串由许多段组成,每个段都有一个类型。 位字符串中使用了9种类型: - integer - float - bits (别名为 bitstring ) - 位字符串 - binary - bytes (别名为 二进制的 ) - utf8 - utf16 - utf32 未指定类型时,默认值为 整数

    例如, << d::integer-size(80), rest::binary >> = date 会给你和你报告的一样的结果。