0

I'm trying to parse in json a txt file content. This is the file content:

[19-02-2016 16:48:45.505547] [info] System done. 
 0: array(
 'ID' => 'Example 2'
 )

Now this is my code for parse the file:

$fh = fopen($file, "r");
$content = array(); 
$content["trace"] = array();
while ($line = fgets($fh))
{
 $raw = preg_split("/[\[\]]/", $line); 
 $entry = array();
 $entry["date"] = trim($raw[1]);
 $entry["type"] = trim($raw[3]);
 $entry["message"] = trim($raw[4]);
 $content["trace"][] = $entry;
}
fclose($fh);
return $content;

and this is what is returned from $content:

{
 "trace": [{
 "date": "19-02-2016 16:48:45.505547"
 "type": "info"
 "message": "System done."
 }, {
 "date": ""
 "type": ""
 "message": ""
 }, {
 "date": ""
 "type": ""
 "message": ""
 }, {
 "date": ""
 "type": ""
 "message": ""
 }]
}

UPDATE I'm expecting this:

{
 "trace": [{
 "date": "19-02-2016 16:48:45.505547"
 "type": "info"
 "message": "System done."
 "ID": Example 2
 }]
}

how you can see the array is saw as a new line and the code create other empty array in the while without content. I just want create new index later message and put the array content, how I can achieve this?

UPDATE WITH MORE CONTENT IN FILE

[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. 
 0: array(
 'ID' => 'john foo'
 )

Expected result:

{
"trace": [20]
0: {
"date": "19-02-2016 16:57:17.104504"
"type": "info"
"message": "system done."
"ID": john foo
}
1: {
"date": "19-02-2016 16:57:17.110482"
"type": "info"
"message": "transaction done."
"ID": john foo
}
...
Edson Horacio Junior
3,1933 gold badges34 silver badges53 bronze badges
asked Feb 19, 2016 at 15:53
4
  • Please show us an example of what you are expecting as result. Commented Feb 19, 2016 at 16:03
  • @hherger see my update Commented Feb 19, 2016 at 16:05
  • Is there a case where trace will have more than one object? If there is, please post a sample of source txt file and expected result. Commented Feb 19, 2016 at 16:10
  • 1
    @EdsonHoracioJunior complete example Commented Feb 19, 2016 at 16:14

1 Answer 1

2

Try this:

Code

<?php
$file = 'test.log';
$content = array(); 
$content["trace"] = array();
$input = file_get_contents('test.log');
preg_match_all('/\[(.*)\][\s]*?\[(.*?)\][\s]*?(.*)[\s][^\']*\'ID\'[ ]*=>[ ]*\'(.*)\'/', $input, $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;
echo '<pre>'; print_r($content); echo '</pre>'; // For testing only
$content = json_encode($content); // For testing only
echo '<pre>' . $content . '</pre>'; // For testing only

Result

PHP array:

Array
(
 [trace] => Array
 (
 [0] => Array
 (
 [date] => 19-02-2016 16:57:17.104504
 [type] => info
 [message] => system done.
 [ID] => john foo
 )
 [1] => Array
 (
 [date] => 19-02-2016 16:57:17.110482
 [type] => info
 [message] => transaction done.
 [ID] => john foo
 )
 )
)

Json object (string):

{
 "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":"john foo"
 }
 ]
}

Notes re. the RegEx:

  • The file is read as a whole into a string variable ($input).
  • The preg_match_all(RegEx) also scans the entire input.
  • The code iterates over all its hits, where the groups contain these parts…
    • 1: date
    • 2: type
    • 3: message
    • 4: ID
  • The RegEx in detail:

     \[ Match the character "[" literally
    ( Match the regular expression below and capture its match into backreference number 1
     . Match any single character that is not a line break character
     * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
    )
    \] Match the character "]" literally
    [\s] Match a single character that is a "whitespace character" (spaces, tabs, and line breaks)
    *? Between zero and unlimited times, as few times as possible, expanding as needed (lazy)
    \[ Match the character "[" literally
    ( Match the regular expression below and capture its match into backreference number 2
     . Match any single character that is not a line break character
     *? Between zero and unlimited times, as few times as possible, expanding as needed (lazy)
    )
    \] Match the character "]" literally
    [\s] Match a single character that is a "whitespace character" (spaces, tabs, and line breaks)
    *? Between zero and unlimited times, as few times as possible, expanding as needed (lazy)
    ( Match the regular expression below and capture its match into backreference number 3
     . Match any single character that is not a line break character
     * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
    )
    [\s] Match a single character that is a "whitespace character" (spaces, tabs, and line breaks)
    [^'] Match any character that is NOT a "'"
    * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
    'ID' Match the characters "'ID'" literally
    [ ] Match the character " "
    * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
    => Match the characters "=>" literally
    [ ] Match the character " "
    * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
    ' Match the character "'" literally
    ( Match the regular expression below and capture its match into backreference number 4
     . Match any single character that is not a line break character
     * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
    )
    ' Match the character "'" literally
    
answered Feb 19, 2016 at 16:11
Sign up to request clarification or add additional context in comments.

5 Comments

Nope, the result isn't in json content.. I post an example
Your earlier example was a php array. I add it to my answer.
I don't understand how the regex work.. could explain a bit? UPDATE: If I don't have the array, so have only this: [19-02-2016 16:48:45.505547] [info] System done. No content is returned... @hherger
thanks for the regex explaination, there is a condition that I can insert? check my last comment for see the problem, maybe you don't see it.
Do you have mixed one-line entries (withou array...) and multi-line entries (with array...)?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.