正则表达式无法获得堆栈跟踪

时间:2016-02-25 09:57:34

标签: php regex

我有一个这种结构的文件:

[19-02-2016 16:57:17.104504] [info] system done. 
 0: array(
   'ID' => 'john foo'
 )

[19-02-2016 16:57:17.110482] [info] transaction done. 

[25-02-2016 10:44:16.132093] [error] Errore 
0: array(
      'Trace' => 'exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'primo_db.primo_userss' doesn't exist' in C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\core\database.php:44
   Stack trace:
   #0 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\core\database.php(44): PDO->prepare('SELECT * FROM p...')
   #1 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\models\tests_model.php(31): Database->select('SELECT * FROM p...')
   #2 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\controllers\test.php(43): Tests_Model->selectData()
   #3 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\core\router.php(159): Test->selectUser()
   #4 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\core\map.php(52): Router->submit()
   #5 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\system\api.php(110): Map->init_get()
   #6 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\boot.php(21): Api->init()
   #7 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\index.php(18): Boot->__construct()
   #8 {main}'
   )

现在对于前两种情况我没有问题反序列化结构如下(前两个跟踪)第三个跟踪没有被打印我在示例中把它放在我想要实现的结构:< / p>

"trace":[
{
    "date":"19-02-2016 16:57:17.104504",
    "type":"info",
    "message":"system done.",
    "ID":"john foo"
},
{
    "date":"19-02-2016 16:57:17.110482",
    "type":"info",
    "message":"transaction done.",
    "ID":""
 },
 { 
    "date":"25-02-2016 10:44:16.132093",
    "type":"error",
    "message" : "'exception 'PDOException' with message 
'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'primo_db.primo_userss' doesn't exist' in C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\core\database.php:44"
    "stack": "#0 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\core\database.php(44): PDO->prepare('SELECT * FROM p...')
   #1 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\models\tests_model.php(31): Database->select('SELECT * FROM p...')
   #2 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\controllers\test.php(43): Tests_Model->selectData()
   #3 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\core\router.php(159): Test->selectUser()
   #4 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\core\map.php(52): Router->submit()
   #5 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\system\api.php(110): Map->init_get()
   #6 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\boot\boot.php(21): Api->init()
   #7 C:\Bitnami\wampstack-5.5.29-1\apache2\htdocs\api\v1\index.php(18): Boot->__construct()
   #8 {main}'"
 }
]

但是对于error,不显示任何内容,导致regex无法反序列化数据。这是我的代码:

 $fh = file_get_contents($file);

 if(!$fh) { throw new Exception("Not found"); }

 $content = array(); 
 $content["trace"] = array();

 preg_match_all('/\[(.*)\][\s]*?\[(.*?)\][\s]*?(.*)[\s.]+(?:\d+[^\']*\'ID\'[ ]*=>[ ]*\'(.*)\')?/',
 $fh, $regs, PREG_PATTERN_ORDER);

 for($i = 0; $i < count($regs[0]); $i++)
 {
       $content['trace'][] = array(
       'date'    => $regs[1][$i],
       'type'    => trim($regs[2][$i]),
       'message' => trim($regs[3][$i]),
        'ID'      => trim($regs[4][$i]),
            );
  }

  return $content;

我如何解决这个问题? &#39;因为error一般意味着存在具有堆栈跟踪内容的数组..

1 个答案:

答案 0 :(得分:0)

您可以尝试这种递归模式:

/\[(?<date>[^]]*)\]\h*\[(?<type>[^]]*)\]\h*(?<msg>[^\r\n]*)(?:\R\h*\d+:\h*array(?<message>\((?:[^()]*|(?-1))*\)))?/s

RegEx Demo

PS:它会在上次捕获的群组中提供额外的) 'Trace' => ',您可以通过后期处理删除。