Лучше взглянуть на исходный код Linux 0.01 . это первая версия ОС. это очень просто и информативно. Это хорошее место для начала
Можно использовать аннотации (макросы) 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.
Обратите внимание, что:
У вас действительно нет особого выбора, кроме как заранее запустить регулярное выражение и затем сопоставить результаты с образцом. Вот очень простой пример, который приближается к тому, что, как я думаю, вам нужно, но он страдает недостатком, заключающимся в том, что вам нужно повторять регулярные выражения дважды. Вы могли бы сделать это менее болезненным, используя макрос для определения каждого регулярного выражения в одном месте.
-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]).
Вы можете использовать модуль 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)
...
Вы не можете сопоставить шаблон в регулярных выражениях, извините. Итак, вам нужно сделать
my_function(String) -> Matches = re:run(String, "^[A-Za-z]+[A-Za-z0-9]*$"),
...
Для строки вы можете использовать модуль re: после этого вы перебираете результирующий набор. Боюсь, что нет другого способа сделать это AFAIK: именно поэтому существуют регулярные выражения.
Для заголовков HTTP, поскольку их может быть много, я бы рассмотрел итерацию по набору результатов, чтобы быть лучшим вариантом вместо написания очень длинного выражения (потенциально).
Работа EEP: я не знаю.