Parsare JSON „ușor” invalid

Am un string JSON cu următoarea structură:

{
  foo: [],
  bar: [],
}

Problema constă în ultima virgulă, care poate fi sau poate nu fi prezentă.

Există vreo modalitate prin care aș putea parsa respectivul string?

Soluția adoptată în momentul ăsta este să fac preg_replace la tot ce înseamnă ,} sau ,], dar mi se pare ușor hacky.

$json = preg_replace("/,(\s+)(\]|\})/", "$2", $json)
Nu că aș avea nevoie _acum_, dar problema cea mai mare este că nu păstrează formatarea textului (i.e. linii noi și/sau spații multiple).
//varianta veche
$json = preg_replace("/\n|\t|\s{2,}/", "", $json);
$json = preg_replace('/,(\}|\])/', '$1', $json);
var_dump(json_decode($json);

Ultima virgula nu ar avea voie sa fie acolo daca vorbim de un JSON standard. Am avut si eu problema asta undeva unde generam structuri JSON si trebuia sa tai intotdeauna ultima virgula (din generare) ca sa poata fi parsata structura de alte coduri si librarii.

Păi știu, tocmai de aia am precizat că-i ușor invalid :smiley:

Eu chestia asta o fac din generare, cand trec de randul cu virgula aia fac trim la virgula si adaug terminatorul de structura (cum e la tine } ). Nu lucrez in PHP dar e acelasi lucru. Banuiesc ca e un sir generat de mana avand in vedere ca are virgula aia, ai putea umbla acolo… Altfel e mai de complicat sa extragi virgula din stringul final mai ales daca vei avea structuri imbricate cu virgule invalide.

Asta nu e prea e o opțiune, pentru că nu am cum să alterez string-ul respectiv…

https://github.com/hjson/hjson-php - poate te ajuta, eu am folosit versiunea Java pentru un JSON care urma sa fie scris de niste oameni si tot timpul ba aveam virgule in plus, ba erau comentarii in el, etc. HJSON e detaliat la https://hjson.org/ .

7 Likes

Replace a regex with a full blown library that implements another specification? If that’s not a hot spot, hell yeah!

interesant cum se comporta in Ruby:

{"foo"=>[], "bar"=>[]}
{"foo"=>[], "bar"=>[]}
{"foo"=>[], "bar"=>[]}

Warming up --------------------------------------
           JSON::Ext    32.814k i/100ms
               Hjson   330.000  i/100ms
                  Oj    49.686k i/100ms
Calculating -------------------------------------
           JSON::Ext    396.235k (± 2.6%) i/s -      2.002M in   5.055496s
               Hjson      3.260k (± 5.2%) i/s -     16.500k in   5.077614s
                  Oj    645.841k (± 4.6%) i/s -      3.230M in   5.012269s

Comparison:
                  Oj:   645840.8 i/s
           JSON::Ext:   396235.5 i/s - 1.63x  slower
               Hjson:     3259.5 i/s - 198.14x  slower

Calculating -------------------------------------
           JSON::Ext   608.000  memsize (     0.000  retained)
                         9.000  objects (     0.000  retained)
                         2.000  strings (     0.000  retained)
               Hjson    47.248k memsize (     0.000  retained)
                       918.000  objects (     0.000  retained)
                        50.000  strings (     0.000  retained)
                  Oj   472.000  memsize (     0.000  retained)
                         8.000  objects (     0.000  retained)
                         2.000  strings (     0.000  retained)

Comparison:
                  Oj:        472 allocated
           JSON::Ext:        608 allocated - 1.29x more
               Hjson:      47248 allocated - 100.10x more

Evident depinde de implementare si limbaj - insa atentie la memoria alocata si viteza - daca sunt relevante (in contextul meu - clar nu l-as folosi)