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 作为二进制文件的大小减去开始。
如果Start 或Start + Length 超出输入字符串,则函数会引发异常,如page you linked to 中进一步记录的那样:
如果在选项中指定了{scope, {Start,Length}},则Start > 大小
Subject、Start + 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 位)字符。