Как проанализировать неверный JSON с ключами без кавычек, используя ActiveSupport 3 (Rails) - PullRequest
9 голосов
/ 03 февраля 2011

Мне нужно проанализировать недопустимый JSON в Ruby.

Что-то вроде:

json_str = '{name:"Javier"}'
ActiveSupport::JSON.decode json_str

Как видите, он недействителен, потому что ключ хеша не указан в кавычках, он должен быть1006 *

json_str = '{"name":"Javier"}'

Но это не может быть изменено, и я должен разобрать ключи без кавычек.

Я мог бы проанализировать его с ActiveSupport 2.x, но ActiveSupport 3 не позволяет мне.Меня бросает:

Yajl::ParseError: lexical error: invalid string in json text.
                                      {name:"Javier"}
                     (right here) ------^

Кстати, это приложение Ruby, использующее некоторые библиотеки Rails, но это не приложение Rails

Заранее спасибо

Ответы [ 3 ]

2 голосов
/ 18 августа 2011

Я бы использовал регулярное выражение, чтобы исправить этот неверный JSON:

json_str = '{name:"Javier"}'
json_str.gsub!(/(['"])?([a-zA-Z0-9_]+)(['"])?:/, '"\2":')
hash = Yajl::Parser.parse(json_str)
0 голосов
/ 06 декабря 2012

Вот несколько надежных регулярных выражений, которые вы можете использовать.Он не идеален - в частности, он не работает в некоторых угловых случаях, когда сами значения содержат json-подобный текст, но он будет работать в большинстве общих случаев:

quoted_json = unquoted_json.gsub(/([{,]\s*)(\w+)(\s*:\s*["\d])/, '\1"\2"\3')

Сначала он ищет либо { или ,, которые являются опциями для символа, предшествующего имени ключа (также допускается любое количество пробелов с \s*).Он захватывает это как группу:

([{,]\s*)

Затем он захватывает сам ключ, который состоит из букв, цифр и символов подчеркивания (для которого удобно использовать регулярное выражение \w класс символов):

(\w+)

Наконец, оно соответствует тому, что должно следовать за именем ключа;то есть двоеточие, за которым следует либо начальная кавычка (для строкового значения), либо цифра (для числового значения).Также допускает дополнительные пробелы и захватывает все в группе:

(\s*:\s*["\d])

Для каждого матча он просто складывает три фигуры вместе, но с кавычками вокруг ключа (поэтому кавычки вокруг группы захвата # 2):

'\1"\2"\3'
0 голосов
/ 03 февраля 2011

Как то так?

require 'json'
json_str = '{name:"Javier"}'
hash = JSON::parse( json_str.gsub( /{|:"/, {'{'=>'{"', ':"'=>'":"'} ) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...