Вызов: бинарный модуль Erlang из Elixir, но возникли проблемы с опциями - PullRequest
0 голосов
/ 16 мая 2018

Я стремлюсь найти в строке, начиная с определенного индекса. Кажется, я ищу : binary.match / 3 , но у меня проблемы с опциями. Из документации кажется, что он ожидает список, содержащий один кортеж, содержащий область действия и часть. Я нигде не могу найти, что означает «сфера», но я также не уверен, правильно ли я звоню из Эликсира.

Вот то, что я пытаюсь сделать, но я получаю ошибку аргумента:

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

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

Любая помощь будет оценена. Спасибо!

1 Ответ

0 голосов
/ 16 мая 2018

Документация 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}} (или {:scope, {start, length}} в Elixir) с Start в качестве индекса (на основе 0) и Length в качестве размера двоичного файла без начала.

Если Start или Start + Length находятся за пределами входной строкифункция вызывает исключение, как описано далее на странице , на которую вы ссылаетесь :

Если в параметрах указано {scope, {Start,Length}}, например Start> size Subject, Start + Length <0 или <code>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 можно считать списком ключевых слов , так как все элементы являются кортежами двух элементов, в которыхПервый атом.Квадратные скобки могут быть опущены, это даже считается хорошей практикой , так как опции являются необязательными, и вы можете вместо этого позвонить :binary.match/2.

Обратите внимание, что вам следует использовать byte_size/1 здесь, а не String.length/1 поскольку они (не обязательно) возвращают одно и то же значение.String.length/1 возвращает количество символов, в то время как byte_size/1 возвращает количество байтов - и это то, что функция binary:match/3 ожидает (и возвращает).Разница возникает с не ASCII (7 битами) символами, которые закодированы как несколько байтов.

...