Ben Sinclair
Ben Sinclair

Reputation: 3986

preg_match_all with multiple lines

I'm creating a script that finds all the error_log files on my server. Here's a sample of a typical error_log file:

[08-Feb-2012 05:45:56] PHP Fatal error: Uncaught exception 'Swift_RfcComplianceException' with message 'Address in mailbox given [] does not comply with RFC 2822, 3.6.2.' in /lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php:308
Stack trace:
#0 /lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php(238): Swift_Mime_Headers_MailboxHeader->_assertValidAddress('')
#1 /lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php(96): Swift_Mime_Headers_MailboxHeader->normalizeMailboxes(Array)
#2 /lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php(60): Swift_Mime_Headers_MailboxHeader->setNameAddresses(Array)
[08-Feb-2012 05:46:18] PHP Fatal error: Uncaught exception 'Swift_RfcComplianceException' with message 'Address in mailbox given [] does not comply with RFC 2822, 3.6.2.' in /lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php:308
Stack trace:
#0 /lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php(238): Swift_Mime_Headers_MailboxHeader->_assertValidAddress('')
#1 /lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php(96): Swift_Mime_Headers_MailboxHeader->normalizeMailboxes(Array)
#2 /lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php(60): Swift_Mime_Headers_MailboxHeader->setNameAddresses(Array)
[15-Feb-2012 15:39:10] PHP Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting ']' in /settings.php on line 47

I've used the following code to extract each error individually so I can display them for easy viewing

preg_match_all('/\[\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2}\].*/', $error_log_file, $error_log_parts);

It worked but the problem was it wasn't selecting multiple lines.

Array
(
    [0] => Array
    (
        [0] => [08-Feb-2012 05:45:56] PHP Fatal error:  Uncaught exception 'Swift_RfcComplianceException' with message 'Address in mailbox given [] does not comply with RFC 2822, 3.6.2.' in /home/elvanto/public_html/lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php:308
        [1] => [08-Feb-2012 05:46:18] PHP Fatal error:  Uncaught exception 'Swift_RfcComplianceException' with message 'Address in mailbox given [] does not comply with RFC 2822, 3.6.2.' in /home/elvanto/public_html/lib/SwiftMailer/classes/Swift/Mime/Headers/MailboxHeader.php:308
        [2] => [15-Feb-2012 15:39:10] PHP Parse error:  syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting ']' in /home/elvanto/public_html/roster-settings.php on line 47
    )

)

So I added an 's' to the end:

preg_match_all('/\[\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2}\].*/s', $error_log_file, $error_log_parts);

But now it seems to select everything. I need a way to select everything until it comes to a new date. E.g: [08-Feb-2012 05:46:18]

What code would I need to add to do this?

Upvotes: 0

Views: 879

Answers (1)

mathematical.coffee
mathematical.coffee

Reputation: 56935

Try something like

/\[\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2}\].*?(?=^\[)/s

The .* has been turned into non-greedy .*?, and (?=^\[) has been added to force the .*? to match up until it finds a newline starting with [.

As an aside, you could just successively read in lines of the log file, starting a new array entry if you see a \[\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2}\] and concatenating to the current array entry otherwise - then you don't have to fart around with the .*/s switch.

Upvotes: 1

Related Questions