-2

Here is an example of a log file entry:

[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details: {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}

The {"api_url":"https:\/\/api.wordpress.... portion is valid JSON, but obviously the entire string itself (the log entry line) isn't. I'm hitting a wall with a way to essentially pull out that JSON without messing up any other part of the string.

Norcross
  • 137
  • 1
  • 5

3 Answers3

2

Use preg_match_all to find all the JSON and store it into an array like so:

$text = '[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details: {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}';

preg_match_all('/\{(?:[^{}]|(?R))*\}/x', $text, $matches);

echo '<pre>';
print_r($matches[0]);

This yields:

Array
(
    [0] => {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}
)

You can read up more from: Extracting the JSON string from given text

OR if you want the opposite and remove the JSON out and keep the string then you can use preg_replace to do this:

$text = '[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details: {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}';

$cleantext = preg_replace('~\{(?:[^{}]|(?R))*\}~', '', $text);

echo $cleantext;

Credit from PHP: How to extract JSON strings out of a string dump

This yields:

[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details:
dmotors
  • 611
  • 2
  • 7
  • 19
1

You could try to get the start and end of the the json object and decode it. If there isn't a json decode error then you're good. This assumes that the characters { and } are only used in the json body.

function checkIfStringHasValidJson($string)
{
    $start = strpos($string, '{');
    $end = strrpos($string, '}');
    $json = substr($string, $start, $end);
    json_decode($json);
    return json_last_error() === JSON_ERROR_NONE;
}
Jason Grim
  • 413
  • 4
  • 7
0

Simply remove everything from the string before and including the given substring of "Details:":

$s = '[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details: {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}';
$out = str_replace('Details: ', '', strstr($s, 'Details:'));
echo var_export(json_decode($out));
whitwhoa
  • 2,389
  • 4
  • 30
  • 61