我在RFC 2396和RFC 3986上找到了一个URL解析器正则表达式。
^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
我将它转换为Ragel:
%%{
# RFC 3986 URI Generic Syntax (January 2005)
machine url_parser;
action pchar {
printf("%c", fc);
}
action scheme { printf("scheme\n"); }
action scheme_end { printf("\nscheme_end\n"); }
action authority { printf("authority\n"); }
action authority_end { printf("\nauthority_end\n"); }
action path { printf("path\n"); }
action path_end { printf("\npath_end\n"); }
action query { printf("query\n"); }
action query_end { printf("\nquery_end\n"); }
action fragment { printf("fragment\n"); }
action fragment_end { printf("\nfragment_end\n"); }
scheme = (any - [:/?#])+ >scheme $pchar %scheme_end ;
authority = (any - [/?#])* >authority $pchar %authority_end ;
path = (any - [?#])* >path $pchar %path_end ;
query = (any - [#])* >query $pchar %query_end ;
fragment = (any)* >fragment $pchar %fragment_end ;
main := (( scheme ":" )?) <: (( "//" authority )?) <: path ( "?" query )? ( "#" fragment )?;
}%%
#include <cstdio>
#include <cstdlib>
#include <string>
/** Data **/
%% write data;
int main(int argc, char **argv) {
std::string str(argv[1]);
char const* p = str.c_str();
char const* pe = p + str.size();
char const* eof = pe;
int cs = 0;
%% write init;
%% write exec;
return p - str.c_str();
}
输入绝对URI时它起作用。
liangxu@dev64:~$ ./uri_test "http://www.ics.uci.edu/pub/ietf/uri/?c=www&rot=1&e=%20%20"
scheme
http
scheme_end
authority
www.ics.uci.edu
authority_end
path
/pub/ietf/uri/
path_end
query
c=www&rot=1&e=%20%20
query_end
当我输入权限和路径时成功:
liangxu@dev64:~$ ./uri_test "//www.ics.uci.edu/pub/ietf/uri/?c=www&rot=1&e=%20%20"
authority
www.ics.uci.edu
authority_end
path
/pub/ietf/uri/
path_end
query
c=www&rot=1&e=%20%20
query_end
但是当我只输入路径时失败了:
liangxu@dev64:~$ ./uri_test "/pub/ietf/uri"
出了什么问题?
答案 0 :(得分:0)
你使用了错误的监护人<:
,一旦权限部分看到你的第一个/
,控制权就会被授予权限部分。
如果您看到<:
的别名
expr $(unique_name,1) . expr >(unique_name,0)
这意味着,在左边的expr上匹配的每个过渡状态下,它将保持HIGHER优先级,避免正确表达。
如果你将ABNF符号转换为ragel,那就容易多了。
答案 1 :(得分:0)
我最近自己做了同样的事情,你可以看看我的ragel语法https://github.com/maximecaron/ragel-url-parser