Я хотел бы отменить мой системный журнал.
Мой системный журнал выглядит так:
[ 2016-03-17T15:52:00+08:00 ] 0.0.0.0 /Pwebshell/index.php/Log/GetLog
INFO: [ route_check ] --START--
INFO: CheckRoute Behavior ::run [ RunTime:0.001000s ]
INFO: [ route_check ] --END-- [ RunTime:0.001000s ]
INFO: [ app_begin ] --START--
INFO: ReadHtmlCache Behavior ::run [ RunTime:0.001000s ]
INFO: [ app_begin ] --END-- [ RunTime:0.001000s ]
[ 2016-03-17T15:52:16+08:00 ] 0.0.0.0 /Pwebshell/index.php/Log/GetLog
INFO: [ route_check ] --START--
INFO: CheckRoute Behavior ::run [ RunTime:0.000000s ]
INFO: [ route_check ] --END-- [ RunTime:0.001000s ]
INFO: [ app_begin ] --START--
INFO: ReadHtmlCache Behavior ::run [ RunTime:0.000000s ]
INFO: [ app_begin ] --END-- [ RunTime:0.000000s ]
Я хотел бы напечатать это так:
[ 2016-03-17T15:52:16+08:00 ] 0.0.0.0 /Pwebshell/index.php/Log/GetLog
INFO: [ route_check ] --START--
INFO: CheckRoute Behavior ::run [ RunTime:0.000000s ]
INFO: [ route_check ] --END-- [ RunTime:0.001000s ]
INFO: [ app_begin ] --START--
INFO: ReadHtmlCache Behavior ::run [ RunTime:0.000000s ]
INFO: [ app_begin ] --END-- [ RunTime:0.000000s ]
[ 2016-03-17T15:52:00+08:00 ] 0.0.0.0 /Pwebshell/index.php/Log/GetLog
INFO: [ route_check ] --START--
INFO: CheckRoute Behavior ::run [ RunTime:0.001000s ]
INFO: [ route_check ] --END-- [ RunTime:0.001000s ]
INFO: [ app_begin ] --START--
INFO: ReadHtmlCache Behavior ::run [ RunTime:0.001000s ]
INFO: [ app_begin ] --END-- [ RunTime:0.001000s ]
Что я уже пробовал:
1 Прежде всего, я читаю журнал, используя file_get_contents
$content = file_get_contents('log');
2 Затем я использовал регулярное выражение для выбора записей.
preg_match_all('#(\[\s+\d{4}\-\d{2}\-\d{2}.*\].*?)\[\s+\d{4}\-\d{2}\-\d{2}#s', $content, $matches);
3 я буду использовать array_reverse
перевернуть журнал.
Но $matches
не были правильно выбраны регулярным выражением.
Есть три отдельных вопроса с регулярным выражением:
.*
быть нечестивым, иначе это будет соответствовать до финала ]
в файле.\[\s+\d{4}\-\d{2}\-\d{2}
(то есть он фиксирует начало следующей записи). Это означает, что будут возвращены только некоторые совпадения. Чтобы исправить это, нам нужно преобразовать финальную часть в предварительное утверждение, используя (?=...)
,Что-то вроде следующего должно исправить эти три проблемы.
preg_match_all('#(\[\s+\d{4}\-\d{2}\-\d{2}.*?\].*?)(?=\[\s+\d{4}\-\d{2}\-\d{2}|$)#s', $content, $matches);
Однако ваши записи, кажется, разделены двойными переводами строки. Почему бы просто не разделить журнал на эти? Предполагая, что вы не получите двухсторонние переводы в данных журнала, это будет проще для чтения, быстрее и менее подвержено ошибкам.
Следующее будет работать на Linux:
$lines = explode("\n\n", $content);
$lines = array_reverse($lines);
echo implode("\n\n", $lines);
В Windows вам может потребоваться заменить \n\n
с \r\n\r\n
,
Усовершенствованное решение, которое будет работать независимо от типа перевода строки, с учетом пробелов между переводами строки и вывода с использованием конца строки в вашей системе, может выглядеть следующим образом:
$lines = preg_split("#\r?\n\s*\n#", $content);
$lines = array_reverse($lines);
echo implode(PHP_EOL . PHP_EOL, $lines);
Это также учитывает тот факт, что содержимое вашего журнала иногда содержит более двух строк, разделяющих записи.
Других решений пока нет …