регулярное выражение для добавления двойных кавычек вокруг ключей в JavaScript - PullRequest
5 голосов
/ 30 января 2011

Я использую функцию jQuery getJSON, чтобы сделать запрос и обработать ответ JSON. Проблема в том, что ответ, который я получаю, искажен, и я не могу его изменить. Ответ выглядит примерно так:

{
    aNumber: 200,    
    someText: '\'hello\' world',
    anObject: {
        'foo': 'fooValue',
        'bar': '10.0'
    } 
}

Чтобы быть действительным JSON, оно должно выглядеть так:

{
    "aNumber": 200,    
    "someText": "'hello' world",
    "anObject": {
        "foo": "fooValue",
        "bar": "10.0"
    } 
}

Я хотел бы изменить возвращаемый текст на допустимый объект JSON. Я использовал функцию замены javascript, чтобы превратить одинарные кавычки в двойные, а экранированные одинарные кавычки в одинарные, но теперь я застрял в поиске лучшего способа добавления кавычек вокруг ключевых значений. Например, как бы я изменил foo: "fooValue" на "foo": "fooValue"? Есть ли регулярное выражение, которое может сделать это легко?

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

Ответы [ 5 ]

11 голосов
/ 26 марта 2015

Это регулярное выражение сделает свое дело

$json = preg_replace('/([{,])(\s*)([A-Za-z0-9_\-]+?)\s*:/','$1"$3":',$json);

Хотя это php!Я предполагаю, что это не проблема, преобразовывая это в JS.

8 голосов
/ 05 августа 2014

Я пытался решить ту же проблему, используя regEx в Javascript.У меня есть приложение, написанное для Node.js для анализа входящего JSON, но я хотел «расслабленную» версию синтаксического анализатора (см. Следующие комментарии), так как неудобно помещать кавычки вокруг каждого ключа (имени).Вот мое решение:

var objKeysRegex = /({|,)(?:\s*)(?:')?([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)(?:')?(?:\s*):/g;// look for object names
var newQuotedKeysString = originalString.replace(objKeysRegex, "$1\"$2\":");// all object names should be double quoted
var newObject = JSON.parse(newQuotedKeysString);

Вот разбивка regEx:

  • ({|,) ищет начало объекта, { для плоских объектов или , для встроенных объектов.
  • (?:\s*) находит, но не запоминает пробел
  • (?:')? находит, но не запоминает ни одной кавычки (будет заменена двойной кавычкой позже).Будет либо ноль, либо один из них.
  • ([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*) - это имя (или ключ).Начинается с любой буквы, подчеркивания, $ или точки, за которыми следуют ноль или более буквенно-цифровых символов, или подчеркивание, или тире, или точка, или $.
  • последний символ : - это то, что разделяет имя объектаот значения.

Теперь мы можем использовать replace() с некоторыми повязками для получения наших недавно цитируемых ключей:

originalString.replace(objKeysRegex, "$1\"$2\":")

, где $1 равен либо {, либо, в зависимости от того, был ли объект внедрен в другой объект.\" добавляет двойную кавычку.$2 это имя.\" еще одна двойная кавычка.и наконец : заканчивает это.Проверьте это с помощью

{keyOne: "value1", $keyTwo: "value 2", key-3:{key4:18.34}}

output:

{"keyOne": "value1","$keyTwo": "value 2","key-3":{"key4":18.34}}

Некоторые комментарии:

  • Я не тестировал этот метод на скорость, но из того, что я собралПри прочтении некоторых из этих записей, использование регулярных выражений происходит быстрее, чем eval()
  • . Для моего приложения я ограничиваю символы, которые имена могут иметь с ([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*) для моей «расслабленной» версии JSON.синтаксический анализатор.Если вы хотите разрешить больше символов в именах (вы можете сделать это и при этом иметь действительный JSON), вы можете вместо этого использовать ([^'":]+) для обозначения чего-либо, кроме двойных или одинарных кавычек или двоеточия.Это по-прежнему будет ограничивать вас больше, чем стандарт JSON (который допускает одинарные кавычки в имени), но тогда вы не сможете выполнить синтаксический анализ с помощью этого метода.С этим выражением ([^'":]+) вы можете иметь все виды вещей, поэтому будьте осторожны.

Надеюсь, это поможет.

3 голосов
/ 30 января 2011

изменить & mdash; снова и снова обратил внимание на то, что эту проблему нельзя решить с помощью регулярного выражения.

Важно различать нотацию JSON как сериализованную форму и нотацию константы объекта JavaScript.

Это:

{ x: "hello" }

- это совершенно правильное значение JavaScript (фрагмент выражения), так что это:

var y = { x: "hello" };

дает вам точно такой же результат, как:

var y = { "x": "hello" };

Другими словами, значение "y" в любом из этих случаев будет точно таким же. Совершенно точно так же, что невозможно было бы сказать, какая из этих двух констант использовалась для инициализации «у».

Теперь, если вы хотите перевести строку , содержащую стиль JSON "Сокращения JSON" без кавычек, в допустимый JSON, единственное, что нужно сделать, - это проанализировать и восстановить строку с кавычками вокруг имена свойств. То есть вам придется либо написать свой собственный «расслабленный» синтаксический анализатор JSON, который может справиться с идентификаторами без кавычек в качестве имен свойств, либо найти готовый синтаксический анализатор, который может обрабатывать такой смягченный синтаксис.

В вашем случае, похоже, что когда у вас есть «расслабленный» парсер, все готово; Вам не нужно переводить обратно. К счастью, ваш «неверный» ответ JSON полностью интерпретируется самим JavaScript, поэтому, если вы доверяете источнику данных (а это большой «если»), вы сможете оценить его с помощью «eval ()» .

0 голосов
/ 30 января 2011

Поскольку это неправильно сформированный «JSON», вы не сможете использовать jQuery.getJSON.

Вы можете использовать

jQuery.ajax({
      url : myUrl,
      data : myParams,
      type : "GET",
      success : function(jsontext)
      {
          // jsontext is in text format
          jsontext = jsontext.replace("'", "\"");
          // now convert text to JSON object
          var jsonData = eval('(' + jsontext+ ')');

          // rest of the code
      }
 });
0 голосов
/ 30 января 2011

Вам не нужно делать это - у вас уже есть действительный объект JSON .Прочитайте о JSON здесь .

Если вам нужно получить значение, просто напишите data.whatever, и оно просто работает.Например: если у вас есть JSON object data:

{
  moo: "foo",
  foo: "bar"
}

Все возможные поля moo и foo и их использование data.moo и data.foo соответственно.И если вы хотите использовать data в качестве аргумента jQuery, просто передайте его как есть: $.load("http://my.site.com/moo", data, function(response){ /* ... */ }).

Примечание: в последнем примере, который я упомянул, ответбудет строкаЧтобы сделать его действительным объектом JSON, используйте метод $.parseJSON(response);.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...