【问题标题】:Calling :binary.match Erlang module from Elixir but having trouble with options从 Elixir 调用 :binary.match Erlang 模块但遇到选项问题
【发布时间】:2018-10-26 09:51:36
【问题描述】:

我的目标是在字符串中查找,从某个索引开始。似乎:binary.match/3 是我要寻找的,但我在选择时遇到了问题。从文档来看,它似乎需要一个包含单个元组的列表,其中包含一个范围和一个部分。我在任何地方都找不到“范围”的含义,但我也不确定我是否从 Elixir 正确调用它。

这是我正在尝试的事情,但我不断收到参数错误:

:binary.match(my_str, "foo", [{[], {0, 100}}])

:binary.match(my_str, "foo", [{[], [start: 0, length: 100]}])

任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: erlang elixir


    【解决方案1】:

    Erlang/OTP 文档可能难以阅读,尤其是来自 Elixir 的语法不同时。作为记录,Erlang 中的原子通常以小写字母开头,变量以大写字母开头,而 Elixir 中的变量通常以小写字母开头,原子以冒号开头。这里,scope 只是一个原子。

    函数binary:match/3(来自Elixir 的:binary.match/3)接受一个主题、一个模式和选项作为它的参数。选项指定为:

    Options = [Option]
    Option = {scope, part()}
    part() = {Start :: integer() >= 0, Length :: integer()}
    

    这意味着它是零个或多个Option 的列表,其中Option 是一个元组,scope 原子作为其第一个元素,part() 作为第二个元素。 part() 是一个包含两个元素的元组,Start 是一个非负整数,Length 是一个整数(允许负长度具有不同的记录含义)。根据规范,为binary:match/3 提供多个范围选项是合法的,但未记录在案且结果未定义。

    要从特定索引到二进制末尾搜索二进制文件,请使用元组 {scope, {Start, Length}}(或 Elixir 中的 {:scope, {start, length}}),其中 Start 作为索引(从 0 开始),Length 作为二进制文件的大小减去开始。

    如果StartStart + Length 超出输入字符串,则函数会引发异常,如page you linked to 中进一步记录的那样:

    如果在选项中指定了{scope, {Start,Length}},则Start > 大小 SubjectStart + Length Start + Length > Subject 的大小,会引发 badarg 异常。

    字符串“hello world”的示例用法如下:

    binary:matches(<<"hello world">>, <<"o">>).
    binary:match(<<"hello world">>, <<"o">>, [{scope, {0, byte_size(<<"hello world">>)}}]).
    binary:match(<<"hello world">>, <<"o">>, [{scope, {5, byte_size(<<"hello world">>) - 5}}]).
    

    这些调用分别返回[{4,1},{7,1}]{4,1}{7,1}

    在 Elixir 语法中,这将是:

    :binary.matches("hello world", "o")
    :binary.match("hello world", "o", scope: {0, byte_size("hello world")})
    :binary.match("hello world", "o", scope: {5, byte_size("hello world") - 5})
    

    确实,Options 可以被认为是Keyword list,因为所有元素都是两个元素的元组,其中第一个是原子。括号可以省略,它甚至被认为是good practice,因为选项是可选的,你可以调用:binary.match/2

    请注意,您应该在此处使用 byte_size/1 而不是 String.length/1,因为它们不会(必然)返回相同的值。 String.length/1 返回字符数,而 byte_size/1 返回字节数 - 这是 binary:match/3 函数期望(并返回)的。不同之处在于编码为几个字节的非 ASCII(7 位)字符。

    【讨论】:

    • 出色的答案!!感谢您的详细说明。这将有助于我将来理解 Erlang 文档。我也很感激你解释了我注意到的关于 byte_size / String.length 的奇怪之处
    • 最后2个elixir代码示例的末尾多了一个大括号。
    • @BobWoodley 谢谢,已修复。
    猜你喜欢
    • 2016-10-20
    • 2013-12-05
    • 2015-11-13
    • 2017-12-13
    • 2019-08-27
    • 2013-09-16
    • 2018-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多