我有来自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="
...
);
答案 0 :(得分:1)
我知道这个问题很老,但我刚刚进入Ragel,这可能对其他人有所帮助。
这里的问题是运营商优先级。操作操作符>
和%
在强差异操作符--
之前进行评估。用括号修复很容易:
user_agent = (any* -- ' status=') >mark %{ emit("user_agent"); };
我还会使用space
而不是对空格进行硬编码,至少为了保持一致性:
user_agent = (any* -- (space 'status=')) >mark %{ emit("user_agent"); };
答案 1 :(得分:0)
您可以使用状态图表,尝试此状态机:
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”,对于其他变量,我想你已经知道如何标记&得到角色。