Страницы

Поиск по вопросам

понедельник, 15 июля 2019 г.

Как распарсить JavaScript Object (не валидный JSON) в Golang?

Вначале валидный JSON:
v1 := `{ "middle" : { "src": "pictures/product/middle/14906_middle.jpg", "place" : "#preview-img", "title": "343880-090-slantsy-nike-benassi-just-do-it" } }`
Теперь валидный JavaScript Object, но не валидный JSON:
v2 := `{ middle : { src: 'pictures/product/middle/14906_middle.jpg', place : '#preview-img', title: '343880-090-slantsy-nike-benassi-just-do-it' } }`
Подскажите как распарсить второй вариант? Обычный encoding.json.Unmarshal() ругается на невалидность.
error: invalid character 'm' looking for beginning of object key string
Может быть есть какая-то библиотека в которой этот нюанс можно настроить?
Update:
Можно запустить VM https://github.com/robertkrimen/otto и передав ей немного дополненный текст получить из неё нужное поле.
package main
import ( "testing" "github.com/robertkrimen/otto" )
func BenchmarkVMGet(b *testing.B) { vm := otto.New()
b.ResetTimer() for i := 0; i < b.N; i++ { st := ` { middle : { src: 'pictures/product/middle/14906_middle.jpg', place : '#preview-img', title: '343880-090-slantsy-nike-benassi-just-do-it' } } `
vm.Run(` obj = `+st+` src = obj.middle.src; `) src, err := vm.Get("src") // <----- _ = src _ = err } }
# go test -bench=".*" ottotest testing: warning: no tests to run PASS BenchmarkVMGet 30000 58103 ns/op ok ottotest 2.367s
Однако есть минусы:
может прилететь произвольный кусок текста и выполнять его бездумно не правильно (вспомним eval в php) достаточно медленно используется очень большая библиотека - плохая зависимость
Плюсы:
всё таки достаточно быстро можно не останавливать VM, а пушить туда через Run, но если пушить бесконечно остаётся вопрос - умрёт однажды или не умрёт - без хорошего знания внутренностей библиотеки сказать этого заранее нельзя
Я всё ещё ищу другие варианты, чисто под задачу распарсить object и не выполнять лишних операций.


Ответ

Есть библиотека для этого launchpad.net/rjson. Если ключ соответствует регулярному выражению
[a-zA-Z][a-zA-Z0-9\-_]*
Обращаю внимание, что в JavaScript символ $ может быть использован - а здесь нет.
Однако launchpad.net/rjson не поддерживает одинарные кавычки в значениях. Что бы это поправить был сделан форк который можно взять вот тут: github.com/mantyr/rjson

Комментариев нет:

Отправить комментарий