Регулярное выражение для соответствия значению записи json, которая может содержать квадратные скобки [] - PullRequest
1 голос
/ 27 мая 2020

У меня есть json со следующей структурой:

{
  test1:[value1, value2],
  test2:[value3, value4],
  .....
}

Я пытаюсь сопоставить значение пары ключей test1:[value1, value2]. Проблема в том, что я не всегда знаю, каково значение ключа test1. Кроме того, иногда это может быть не массив, а просто значение. Я пробовал это

"test1":(\[{1})?([^]]+)(\]{1})?(\,)? 

, но он работает, только если значение ключа test1 является только массивом. Если удалить квадратную скобку, она также будет соответствовать второму ключу test2. Другая проблема заключается в том, что я использую инструмент, в котором нет json парсера

Как go можно об этом?

Ответы [ 3 ]

1 голос
/ 27 мая 2020

Регулярные выражения не могут соответствовать вложенным структурам JSON.

Просто используйте вместо этого правильный JSON синтаксический анализатор. Ваш код станет проще и правильнее.

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

1 голос
/ 27 мая 2020

Используйте чередование для обоих случаев:

"test1"\s*:\s*(?:\[[^]]*]|[^,}]+)

См. живую демонстрацию .

Разбивка на части:

  • "test1"\s*:\s* позволяет использовать пробелы вокруг двоеточия
  • (?:...) - это группа без захвата
  • ...|... - это чередование - как logi c OR
  • [^]] - это любой символ, не являющийся правой квадратной скобкой
  • \[[^]]*] - любое количество символов, не являющихся правой квадратной скобкой, окруженный квадратными скобками
  • [^,}]+ - любое количество символов, не являющихся запятыми или закрывающими фигурными скобками (в случае, если совпавший термин является последним json пара ключ: значение
0 голосов
/ 27 мая 2020

Изменить: на основе комментариев плакатов о требованиях регулярного выражения, это должно работать лучше:

"([^"]+(?:\\"[^"]*)*)":\s*(\[[^]]*\]|"[^\\"]+(?:\\"?[^"\\]*)*"|\d+(?:\.\d+)?)

https://regex101.com/r/IROlEW/3/

"([^"]+(?:\\"[^"]*)*)" соответствует ключу, но если вам нужно сопоставить указанный ключ c, его можно заменить любым подходящим ключом, который вам нужен.

(\[[^]]*\]|"[^\\"]+(?:\\"?[^"\\]*)*"|\d+)

Использует чередование, чтобы иметь регистр между массивами \[[^]]*\], строками "[^\\"]+(?:\\"?[^"\\]*)*" (которые могут включать запятые и новые строки) и числами \d+(?:\.\d+)? (которые могут включать десятичные дроби).


Предполагая, что ваша структура удерживается вверх, это должно соответствовать парам ключ-значение.

Как уже упоминалось, это будет работать, только если структура JSON останется прежней, и, вероятно, настоящий парсер JSON будет работать лучше.

"([^"]+)":\s*([^\n,]+(?:,[^\n,]+)*),?

Regex 101 для демонстрации регулярного выражения (и содержит некоторые дополнительные сведения о совпадениях и частях регулярного выражения)

Это регулярное выражение работает путем нахождения ключ, используя:

  • "([^"]+)", что соответствует кавычке, за которой следует без кавычек c символы, за которыми следует кавычка.
  • :\s* для соответствия двоеточию, за которым следует один или несколько символов пробела.
  • ([^\n,]+(?:,[^\n,]+)*) будет выполнять сопоставление основного свойства. - [^\n,]* соответствует символам, которые не являются новой строкой или запятой, один или несколько раз
    • (?:,[^\n,]+)* соответствует запятой, за которой следуют те же символы, не являющиеся новой строкой / запятой. Он будет соответствовать столько раз, сколько сможет, чтобы убедиться, что он покрывает запятые, которые находятся в пределах значения JSON.
  • Затем в конце он необязательно соответствует запятой

Это регулярное выражение основано на предположении, что ключи JSON не содержат внутри себя кавычек, однако его можно расширить, чтобы они были разрешены (сохранены отдельно, потому что это усложняет регулярное выражение):

"([^"]+(?:\\"[^"]*)*)":\s*([^\n,]+(?:,[^\n,]+)*),?

Основное различие между этими двумя состоит в том, что здесь используется та же посылка, что и `([^ \ n,] + (?:, [^ \ N,] +) * ), чтобы разрешить экранированные кавычки в ключах свойств JSON.

Самое большое предположение в обоих из них (на основе данных, которые вы показали) заключается в том, что они не будут работать с многострочными данными как было бы намного сложнее выяснить, где значение заканчивается многострочным JSON.

Вот пример, работающий ниже:

const regex = /"([^"]+(?:\\"[^"]*)*)":\s*([^\n,]+(?:,[^\n,]+)*),?/g

const JSON = `
{
  "test1":[value1, value2],
  "test2":[value3, value4],
  "test":"string is, nice",
  "te":{object: 5, red: "blue"},
  "test\"":'hi',
  .....
}
`

console.log([...JSON.matchAll(regex)])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...