Регулярное выражение для сопоставления групп, которые могут не существовать - PullRequest
1 голос
/ 31 января 2020

Я пытаюсь получить некоторые данные из журналов в приложении. Журналы выглядят так:

*junk* [{count=240.0, state=STATE1}, {count=1.0, state=STATE2}, {count=93.0, state=STATE3}, {count=1.0, state=STATE4}, {count=1147.0, state=STATE5}, etc. ] *junk*

Если count для определенного состояния всегда равно 0, его фактически не будет в журнале вообще, поэтому я не могу гарантировать порядок объектов в журнале (единственное, что они отсортированы в алфавитном порядке по названию штата)

Итак, это также потенциальный журнал:

*junk* [{count=240.0, state=STATE1}, {count=1.0, state=STATE4}, {count=1147.0, state=STATE5}, etc. ] *junk*

Я немного новичок в использовании регулярных выражений и думаю, что переборщил с этим, но это то, что я пытался.

^[^=\n]*=(?:(?P<STATE1>\d+)(?=\.0,\s+\w+=STATE1))*.*?=(?P<STATE2>\d+)(?=\.0,\s+\w+=STATE2)*.*?=(?P<STATE3>\d+)(?=\.0,\s+\w+=STATE3)

Идея в том, что я буду искать ' = 'и затем посмотрите вперед, чтобы увидеть, если это для того состояния, которое я хочу, и оно может или не может быть там. Затем пропустите весь мусор после подсчета до следующего состояния, которое меня интересует ( это часть, с которой у меня возникают проблемы, я считаю ). Иногда это совпадает слишком далеко и пропускает интересующее меня состояние, давая мне плохую ценность. Если я использую ленивый оператор (как выше), иногда он не go достаточно далеко и получает счетчик для состояния , которое находится перед тем, который я хочу в журнале.

Ответы [ 3 ]

1 голос
/ 01 февраля 2020

Вы можете использовать 2 группы захвата, чтобы захватить счет и состояние.

Для захвата, например, STATE1, STATE2, STATE3 и STATE5, вы можете указать числа, используя класс символов с диапазонами и / или чередованием.

{count=(\d+(?:\.\d+)?), state=(STATE(?:[123]|5))}

Объяснение

  • {count= Совпадение буквально
  • ( Захват группа 1
    • \d+(?:\.\d+)? Совпадение 1+ цифр с необязательным десятичным знаком часть
  • ) Закрыть группу
  • , state= Совпадение буквально
  • ( Захват Группа 2
    • STATE(?:[123]|5) Соответствует STATE и задает допустимые числа
  • )} Закрыть группу и сопоставить }

Regex demo


Если вы хотите сопоставить все состояния и цифры:

{count=(\d+(?:\.\d+)?), state=(STATE\d+)}

Regex demo

1 голос
/ 31 января 2020

Посмотрите, работает ли этот подход для вас:

Регулярное выражение: (?<=count=)\d+(?:\.\d+)?(?=, state=(STATE\d+))

Демо

В группе будет ваш штат # и полный совпадением будет значение счетчика

0 голосов
/ 10 февраля 2020

После некоторых экспериментов я пришел к следующему:

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

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

count=(?P<GROUP_NAME_HERE>\d+(?=\.0, state=STATE_NAME_HERE))?

Это можно скопировать и добавить с новым именем состояния и именем группы. Кроме того, если какое-либо из состояний не появляется в строке, оно все равно будет соответствовать следующим состояниям. Например:

count=(?P<G1>\d+(?=\.0, state=STATE_ONE))?(?P<G2>\d+(?=\.0, state=STATE_TWO))?(?P<G3>\d+(?=\.0, state=STATE_THREE))?

будет сопоставлять состояния STATE_ONE и STATE_THREE с именованными группами G1 & G3 в следующей строке, даже если STATE_TWO отсутствует:

[{count=55.0, state=STATE_ONE}, {count=10.0, state=STATE_THREE}]

Я уверен, что это можно улучшить, но это достаточно быстро для меня, и с 11 groups regex101 показывает 803 шагов со временем ~1ms

Вот игровая площадка regex101, с которой можно поиграться: https://regex101.com/r/3a3iQf/1

Обратите внимание на совпадение групп 1,2,3,4,5,6,7,9 и 11. 8 и 10 отсутствуют, и следующие группы по-прежнему совпадают.

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