Как сделать сопоставление с образцом Erlang с помощью регулярных выражений?

Лучше взглянуть на исходный код Linux 0.01 . это первая версия ОС. это очень просто и информативно. Это хорошее место для начала

7
задан SilentGhost 2 November 2009 в 16:18
поделиться

6 ответов

Можно использовать аннотации (макросы) Erlang Web-style в сочетании с модулем re Erlang. Пример, вероятно, лучший способ проиллюстрировать это.

Вот как будет выглядеть ваш окончательный код:

[...]
?MATCH({Regexp, Options}).
foo(_Args) ->
  ok.
[...]

Макрос MATCH будет выполняться непосредственно перед вашей функцией foo . Поток выполнения завершится неудачно, если шаблон регулярного выражения не соответствует.

Ваша функция сопоставления будет объявлена ​​следующим образом:

?BEFORE.
match({Regexp, Options}, TgtMod, TgtFun, TgtFunArgs) ->
String = proplists:get_value(string, TgtArgs),
case re:run(String, Regexp, Options) of
  nomatch ->
    {error, {TgtMod, match_error, []}};
  {match, _Captured} ->
    {proceed, TgtFunArgs}
end.

Обратите внимание, что:

  • BEFORE говорит, что макрос будет выполнен перед вашей целевой функцией (также доступен макрос AFTER).
  • match_error - это ваш обработчик ошибок, указанный в вашем модуле, и содержит код, который вы хотите выполнить, если вы не найдете совпадения (возможно, ничего,
6
ответ дан 6 December 2019 в 08:44
поделиться

У вас действительно нет особого выбора, кроме как заранее запустить регулярное выражение и затем сопоставить результаты с образцом. Вот очень простой пример, который приближается к тому, что, как я думаю, вам нужно, но он страдает недостатком, заключающимся в том, что вам нужно повторять регулярные выражения дважды. Вы могли бы сделать это менее болезненным, используя макрос для определения каждого регулярного выражения в одном месте.

-module(multire).

-compile(export_all).

multire([],_) ->
    nomatch;
multire([RE|RegExps],String) ->
    case re:run(String,RE,[{capture,none}]) of
    match ->
        RE;
    nomatch ->
        multire(RegExps,String)
    end.


test(Foo) ->
    test2(multire(["^Hello","world$","^....$"],Foo),Foo).

test2("^Hello",Foo) ->
    io:format("~p matched the hello pattern~n",[Foo]);
test2("world$",Foo) ->
    io:format("~p matched the world pattern~n",[Foo]);
test2("^....$",Foo) ->
    io:format("~p matched the four chars pattern~n",[Foo]);
test2(nomatch,Foo) ->
    io:format("~p failed to match~n",[Foo]).
6
ответ дан 6 December 2019 в 08:44
поделиться

Вы можете использовать модуль re:

re:run(String, "^[A-Za-z]+[A-Za-z0-9]*$").
re:run(String, "^[A-Za-z]+[A-Za-z0-9]*$", [caseless]).

EDIT:

match(String, Regexps) -> 
  case lists:dropwhile(
               fun({Regexp, Opts}) -> re:run(String, Regexp, Opts) =:= nomatch;
                  (Regexp) -> re:run(String, Regexp) =:= nomatch end,
               Regexps) of
    [R|_] -> R;
    _     -> nomatch
  end.

example(String) ->
  Regexps = ["$RE1^", {"$RE2^", [caseless]}, "$RE3"]
  case match(String, Regexps) of
    nomatch -> handle_error();
    Regexp -> handle_regexp(String, Regexp)
    ...
3
ответ дан 6 December 2019 в 08:44
поделиться

Вы не можете сопоставить шаблон в регулярных выражениях, извините. Итак, вам нужно сделать

my_function(String) -> Matches = re:run(String, "^[A-Za-z]+[A-Za-z0-9]*$"),
                       ...
1
ответ дан 6 December 2019 в 08:44
поделиться
  1. Для строки вы можете использовать модуль re: после этого вы перебираете результирующий набор. Боюсь, что нет другого способа сделать это AFAIK: именно поэтому существуют регулярные выражения.

  2. Для заголовков HTTP, поскольку их может быть много, я бы рассмотрел итерацию по набору результатов, чтобы быть лучшим вариантом вместо написания очень длинного выражения (потенциально).

  3. Работа EEP: я не знаю.

3
ответ дан 6 December 2019 в 08:44
поделиться
  1. Erlang does not handle regular expressions in patterns.
  2. No.
2
ответ дан 6 December 2019 в 08:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: