Обратный бревно, как хвост

Я хотел бы отменить мой системный журнал.

Мой системный журнал выглядит так:

[ 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 не были правильно выбраны регулярным выражением.

2

Решение

Есть три отдельных вопроса с регулярным выражением:

  • Вам понадобится первый .* быть нечестивым, иначе это будет соответствовать до финала ] в файле.
  • Ваше регулярное выражение не будет соответствовать последней записи, потому что за ней не следует другая запись.
  • Каждое совпадение «захватывает» совпадающий текст, включая следующие \[\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);

Это также учитывает тот факт, что содержимое вашего журнала иногда содержит более двух строк, разделяющих записи.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]