我有一个 PHP 脚本,可以从
argv[]
中解析信息片段,但对于如何从长字符串中获取信息有点困惑。我只想要 [msg "something something"]
和 [uri "something something"]
字符串:
[2019 年 2 月 6 日星期三 08:57:54] [错误] [客户端 123.123.123.123] ModSecurity:访问被拒绝,代码为 403(第 2 阶段)。操作员情商 在 REQUEST_HEADERS 处匹配 0。 [文件 “/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_21_protocol_anomalies.conf”] [行“47”] [id“960015”] [rev“1”] [msg“请求缺少接受” 标题”] [严重性“通知”] [版本“OWASP_CRS/2.2.6”] [成熟度“9”] [精度“9”] [标签 “OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_ACCEPT”] [标签 “WASCTC/WASC-21”] [标签“OWASP_TOP_10/A7”] [标签“PCI/6.5.10”] [主机名 “something.net”] [uri“/index.php/admin/”] [unique_id “XFsEAsDzZbMAAGY5i5oAAAAA”]
通过使用广泛的正则表达式,您可以一次提取所有标签信息。然后,您可以使用
array_combine
生成由标签索引的值数组:
preg_match_all('/\[([a-z_]+)\s*([^]]*)\]/', $string, $matches);
$output = array_combine($matches[1], $matches[2]);
输出:
Array (
[error] =>
[client] => 123.123.123.123
[file] => "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"
[line] => "47"
[id] => "960015"
[rev] => "1"
[msg] => "Request Missing an Accept Header"
[severity] => "NOTICE"
[ver] => "OWASP_CRS/2.2.6"
[maturity] => "9"
[accuracy] => "9"
[tag] => "PCI/6.5.10"
[hostname] => "something.net"
[uri] => "/index.php/admin/"
[unique_id] => "XFsEAsDzZbMAAGY5i5oAAAAA"
)
如果您不想在值周围加上引号,请使用
array_map
和 trim
:
$output = array_map(function ($v) { return trim($v, '"'); }, $output);
输出:
Array (
[error] =>
[client] => 123.123.123.123
[file] => /etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_21_protocol_anomalies.conf
[line] => 47
[id] => 960015
[rev] => 1
[msg] => Request Missing an Accept Header
[severity] => NOTICE
[ver] => OWASP_CRS/2.2.6
[maturity] => 9
[accuracy] => 9
[tag] => PCI/6.5.10
[hostname] => something.net
[uri] => /index.php/admin/
[unique_id] => XFsEAsDzZbMAAGY5i5oAAAAA
)
您可以尝试使用正则表达式模式匹配,如下所示 - REGEX
<?php
$re = '`\[(msg|uri) "(.*?)"\]`mi';
$str = '[Wed Feb 06 08:57:54 2019] [error] [client 123.123.123.123] ModSecurity: Access denied with code 403 (phase 2). Operator EQ matched 0 at REQUEST_HEADERS. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"] [line "47"] [id "960015"] [rev "1"] [msg "Request Missing an Accept Header"] [severity "NOTICE"] [ver "OWASP_CRS/2.2.6"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_ACCEPT"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [hostname "something.net"] [uri "/index.php/admin/"] [unique_id "XFsEAsDzZbMAAGY5i5oAAAAA"]';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// matches contains all full match, partial match, so you can use any index to get that values e.g match[0] contains [uri "/index.php/admin/"]
//print_r($matches); // see what is full match, partial match etc
foreach($matches as $match){
$expected[] = $match[2];
}
print_r($expected);
?>
输出:
Array (
[0] => Request Missing an Accept Header
[1] => /index.php/admin/
)