我有来自apache的以下代码行(不能更改apache日志格式):
... referrer=- user_agent=JSON-RPC Client status=200 size=44 ...我正试着用Ragel解析它。我将提取除user_agent之外的所有字段。用户指南说,强差异--确保了第一台机器不包含第二台机器。在我的例子中,我希望匹配任何不包含" status="的内容,这将表示下一个字段。但是,我当前的定义(如下所示)似乎完全跳过了user_agent;我仍然得到status和以下字段。我是否正确地利用了强大的差异?
...
referrer = ^space+ >mark %{ emit("referrer"); };
user_agent = any* -- ' status=' >mark %{ emit("user_agent"); };
status = digit+ >mark %{ emit("status"); };
...
line = (
...
space "referrer="
referrer
space "user_agent="
user_agent
space "status="
status
space "size="
...
);发布于 2015-12-22 21:17:01
我知道这个问题有点老了,但我刚开始接触Ragel,这可能会对其他人有所帮助。
这里的问题是运算符的优先级。操作运算符>和%在强差异运算符--之前求值。使用圆括号可以很容易地修复:
user_agent = (any* -- ' status=') >mark %{ emit("user_agent"); };我也会使用space而不是硬编码一个空格,至少为了一致性:
user_agent = (any* -- (space 'status=')) >mark %{ emit("user_agent"); };发布于 2013-06-06 19:01:37
你可以使用状态图,试试这个状态机:
STATUS := digit+ ' ' @{ fnext SIZE; };
SIZE := digit+;
USER_AGENT =
start: (
's' -> s1 |
[^s] @{ if (!ua_start) ua_start = p; } -> start
),
s1: (
't' -> s2 |
[^t] -> start
),
s2: (
'a' -> s3 |
[^a] -> start
),
s3: (
't' -> s4 |
[^t] -> start
),
s4: (
'u' -> s5 |
[^u] -> start
),
s5: (
's' -> s6 |
[^s] -> start
),
s6: (
'=' @{ fnext STATUS; ua_stop = p - 7; } -> final |
[^=] -> start
)
;
main := "user_agent=" USER_AGENT ;你可以在"ua_start“-> "ua_stop”中获取用户代理,对于其他变量,我认为你已经知道如何标记和获取字符。
https://stackoverflow.com/questions/16360467
复制相似问题