0

I have a string:

<b>08-14-2018 09:24:09</b>,192.168.0.1,{"i":"2018-001370","ln":"FIRST","fn":"TEST","a":"570.00","d":"08\/14\/2018 09:23:00","ca":"550.00","ch":"20.00","chi":"s"},{"terapay_response":{"code":-106,"description":"Missing Check Amount Or Check Info"}}

and I want to match all comma outside the curly braces.

My desired output would be:

[0] : <b>08-14-2018 09:24:09</b>
[1] : 192.168.0.1
[2] : {"i":"2018-001370","ln":"FIRST","fn":"TEST","a":"570.00","d":"08\/14\/2018 09:23:00","ca":"550.00","ch":"20.00","chi":"s"}
[3] : {"terapay_response":{"code":-106,"description":"Missing Check Amount Or Check Info"}}

I tried :

preg_match_all("/\((?:[^{}]|(?R))+\)|[^{},\s]+/", $line, $out);

but the output is different :

[0] : "<b>08-14-2018"
[1] : "09:24:09</b>"
[2] : "192.168.0.1"
[3] : ""i":"2018-001370""
[4] : ""ln":"FIRST""
[5] : ""fn":"TEST""
[6] : ""a":"570.00""
[7] : ""d":"08\/14\/2018"
[8] : "09:23:00""
[9] : ""ca":"550.00""
[10] : ""ch":"20.00""
[11] : ""chi":"s""
[12] : ""terapay_response":"
[13] : ""code":-106"
[14] : ""description":"Missing"
[15] : "Check"
[16] : "Amount"
[17] : "Or"
[18] : "Check"
[19] : "Info""

Thank you.

Al Bassam
  • 9
  • 1
  • 5
  • Your string seems to both HTML and JSON content, both of which are notoriously difficult to parse using a pure regex approach. I would suggest that you go back to the source of the data and see if you can get a better extract. – Tim Biegeleisen Aug 14 '18 at 01:45
  • Would it be better if I save the data with JSON only? – Al Bassam Aug 14 '18 at 01:53
  • are the commas at only the start that you want, is it always the same format? For example [date],[ip],[json]. Looks like a log file to me. `/^(?P[^,]+),(?P[^,]+),(?P.+)$/` something like that (untested). Tested now https://regex101.com/r/OHHPK8/1 – ArtisticPhoenix Aug 14 '18 at 02:08
  • Yes, it's a log. It's always the same format. [date],[ip],[json],[json]. – Al Bassam Aug 14 '18 at 02:10
  • the harder part is the multiple sets of JSON, I'll have to think about that. – ArtisticPhoenix Aug 14 '18 at 02:11
  • It worked but it gets the JSON as one. – Al Bassam Aug 14 '18 at 02:14
  • I know that was what I was hinting at – ArtisticPhoenix Aug 14 '18 at 02:26
  • Nick got it. Thank you @ArtisticPhoenix – Al Bassam Aug 14 '18 at 02:29
  • 5 more minutes and I would have figured it out. I was just thinking that you maybe you can't have `},{` in JSON because it would be `},property:{`. Then I thought maybe if I do a negative lookahead, then he posted that :(. If you had something like this `{{data},{data}}` it would be converted to `[data,data]` as there are no keys, that was what i was thinking. I'm not 100% sure if that is true so I was wavering on it a bit.. – ArtisticPhoenix Aug 14 '18 at 02:34

1 Answers1

0

You could use this regex:

/,(?![^{]*})/

which will find a , which is not within {} (based on this answer) to split the string with preg_split:

$str = '<b>08-14-2018 09:24:09</b>,192.168.0.1,{"i":"2018-001370","ln":"FIRST","fn":"TEST","a":"570.00","d":"08\/14\/2018 09:23:00","ca":"550.00","ch":"20.00","chi":"s"},{"terapay_response":{"code":-106,"description":"Missing Check Amount Or Check Info"}}';
print_r(preg_split('/,(?![^{]*})/', $str));

Output:

Array

(
    [0] => 08-14-2018 09:24:09
    [1] => 192.168.0.1
    [2] => {"i":"2018-001370","ln":"FIRST","fn":"TEST","a":"570.00","d":"08\/14\/2018 09:23:00","ca":"550.00","ch":"20.00","chi":"s"}
    [3] => {"terapay_response":{"code":-106,"description":"Missing Check Amount Or Check Info"}}
)
Nick
  • 138,499
  • 22
  • 57
  • 95