Регулярное выражение: сопоставить повторяющиеся группы с неповторяющимися группами - PullRequest
0 голосов
/ 04 июля 2018

У меня есть строка Json, которая мне нужна для извлечения некоторых данных с помощью Regex в C # Строка выглядит примерно так:

{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3",
  "key4": [
    {
      "arrayKey1": 1,
      "arrayKey2": "something",
      "arrayKey3": "somethingelse"
    },
   {
      "arrayKey1": 2,
      "arrayKey2": "something2",
      "arrayKey3": "somethingelse2"
    },
   {
      "arrayKey1": 3,
      "arrayKey2": "something3",
      "arrayKey3": "somethingelse3"
    }
  ],
  "some very long text here": ""
  "anotherKey": "value",
  "keylast": "valuelast"
}

Я хочу извлечь значения массива с именованными группами, я сделал это с помощью следующего регулярного выражения: (?:"arrayKey1": (?<arrayKey1>[^"]+),[\n\t ]+"arrayKey2": "(?<arrayKey2>[^"]+)",[\n\t ]+"arrayKey3": "(?<arrayKey3>[^"]+)")

Это прекрасно работает, и я получаю каждое совпадение для каждого элемента массива с 3 группами каждого ключа.

Теперь я хочу добавить дополнительное совпадение, которое будет содержать только значение «anotherKey» Я не могу добраться до работы. Вот некоторые регулярные выражения, которые я пробовал, но не работал:

(?:"arrayKey1": (?<arrayKey1>[^"]+),[\n\t ]+"arrayKey2": "(?<arrayKey2>[^"]+)",[\n\t ]+"arrayKey3": "(?<arrayKey3>[^"]+)")(?:[\s\S]*)(?:"anotherKey": "(?<anotherKey>[^"]+)")

Этот действительно получает «anotherKey», но возвращает только первый элемент в массиве, а не все.

Также: https://regex101.com/r/mfXlRs/1

Может кто-нибудь правильно меня поставить?

Спасибо

1 Ответ

0 голосов
/ 04 июля 2018

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

Теперь, после того как вы добавили фрагмент, ищущий anotherKey, но на родительском уровне, ситуация изменилась. Теперь у вас есть только одинарный матч, потому что:

  • Ваше "старое" регулярное выражение соответствует только первому набору arraykeys.
  • Тогда (?:[\s\S]*) соответствует всему до anotherKey, включая оба оставшихся набора arraykeys.
  • Добавленная часть соответствует просто anotherKey.

Возможно, вам следует выполнить сопоставление в 2 отдельных шага:

  • Начните с первого (старого) совпадения, получив 3 совпадения для arraykeys и хранить их где-нибудь.
  • Затем запустите второе совпадение, только для anotherKey.

Добавление + квантификатора к "старой" группе не поможет, потому что если захват Группу сопоставляли несколько раз, тогда группа будет содержать только последнее совпадение.

...