我正在使用插件来解析发送给流利的nginx日志条目,并尝试更改它以便它可选地支持另一个字段。
这是用于解析nginx日志条目config_set_default :expression, %q{/^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/}
我尝试将新字段添加到REGEXP中,如此 -
config_set_default :expression, %q{/^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)"(?<http_x_forwarded_for>[^ ]*)?)?$/}
此REGEXP可以解析日志条目是否具有新字段,但仍为新字段创建命名组,这使得现有测试针对插件中断运行。
我想知道是否有某种方法来指示REGEXP它应该添加命名组,如果该组的值存在,并省略该组,否则。
以下是2个日志条目示例,分别包含和不包含新字段 -
127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0"
127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0" -
答案 0 :(得分:1)
您需要在最后一个字段模式后添加(?:\s+(?<http_x_forwarded_for>\S+))?
个可选的非捕获组。这意味着命名的捕获组应位于可选的非捕获组内,并且应在其前放置\s+
,以便在字段之前考虑任何1个以上的空白字符。
使用
^(?<remote>\S*) (?<host>\S*) (?<user>\S*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^"]*?)(?:\s+\S*)?)?" (?<code>\S*) (?<size>\S*)(?: "(?<referer>[^"]*)" "(?<agent>[^"]*)"(?:\s+(?<http_x_forwarded_for>\S+))?)?$
请参阅regex demo。
注意我将[^ ]
替换为\S
,这更加自然地匹配除空白字符之外的字符和正则表达式。