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
Sandokan
1,1053 gold badges19 silver badges31 bronze badges
-
Please show us an example of what you are expecting as result.hherger– hherger2016年02月19日 16:03:36 +00:00Commented Feb 19, 2016 at 16:03
-
@hherger see my updateSandokan– Sandokan2016年02月19日 16:05:18 +00:00Commented 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.Edson Horacio Junior– Edson Horacio Junior2016年02月19日 16:10:50 +00:00Commented Feb 19, 2016 at 16:10
-
1@EdsonHoracioJunior complete exampleSandokan– Sandokan2016年02月19日 16:14:27 +00:00Commented Feb 19, 2016 at 16:14
1 Answer 1
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
hherger
1,6721 gold badge11 silver badges13 bronze badges
Sign up to request clarification or add additional context in comments.
5 Comments
Sandokan
Nope, the result isn't in json content.. I post an example
hherger
Your earlier example was a php array. I add it to my answer.
Sandokan
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... @hhergerSandokan
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.
hherger
Do you have mixed one-line entries (withou array...) and multi-line entries (with array...)?
lang-php