从字符串中获取2条信息

时间:2019-02-07 02:43:40

标签: php

我有一个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”] [版本“ 1”] [信息“消息缺少接受   标头”] [严重性“ NOTICE”] [ver“ 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”]

2 个答案:

答案 0 :(得分:2)

通过使用广泛的正则表达式,您可以一次提取所有标签信息。然后,您可以使用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_maptrim

$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
)

Demo on 3v4l.org

答案 1 :(得分:1)

您似乎是老会员,但对How to ask a help/question on stackoverflow不太熟悉,这就是为什么我要回答您的问题,但是从今天开始,请在尝试任何有关SO的帮助之前遵循规则。

您可以尝试以下正则表达式模式匹配-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/ 
)

演示: https://3v4l.org/HJ2uB