Как сгруппировать внутри "или" соответствия в регулярном выражении? - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть два вида документов для анализа:

1545994641 INFO: ...

и

'{"deliveryDate":"1545994641","error"..."}'

Я хочу извлечь отметку времени 1545994641 из каждого из них.

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

(\d{10}\s|\"\d{10}\")

В документе 1-го типа оно соответствует временной метке и группирует ее, используя первое выражение в "или "выше (\d{10}\s):

>>> regex = re.compile("(\d{10}\s|\"\d{10}\")")
>>> msg="1545994641 INFO: ..."
>>> regex.search(msg).group(0)
'1545994641 '

(Пока все хорошо.)

Однако во 2-м виде используется второе выражение в" или "(\"\d{10}\") соответствует меткам времени и кавычкам, группируя их.Но мне нужна только временная метка, а не "":

>>> regex = re.compile("(\d{10}\s|\"\d{10}\")")
>>> msg='{"deliveryDate":"1545994641","error"..."}'
>>> regex.search(msg).group(0)
'"1545994641"'

Что я пробовал:

Я решил использовать группу без захвата для цитатыоценки:

(\d{10}\s|(?:\")\d{10}(?:\"))

, но это не работает, поскольку внешняя группа ловит их.

Я также удалил внешнюю группу, но результат тот же.

Нежелательные пути решения:

  • Я могу превзойти этосоздавая группу для каждого выражения в или, но я просто хочу, чтобы она выводила одну группу (чтобы абстрагировать код от регулярного выражения).
  • Я также мог бы использовать 2-й шаг регулярного выражения для захвата временной меткииз группы, которая имеет кавычки, но опять-таки это нарушило бы абстракцию кода.
  • Я мог бы опустить "" в регулярном выражении, но , которое будет соответствовать метке времени в середине сообщения , поскольку я хочу, чтобы было объективно зафиксировать метку времени в качестве значения ключа или в начале документа, за которым следует пробел.

Есть ли способ сопоставить обаслучаи выше, но, если это соответствует второму случаю, вернуть только метку времени?Или это невозможно?

EDIT: Как заметил @Amit Bhardwaj, первый случай также возвращает пробел после отметки времени.Это еще одна проблема (я не понял) с тем же решением, вероятно!

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

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

"?(\d{10})(?:\"|\s)

РЕДАКТИРОВАТЬ:

Учитывая, если естьэто первое "должно быть", попробуйте это:

(^\d{10}\s|(?<=\")\d{10}(?=\"))

РЕДАКТИРОВАТЬ 2:

Чтобы также удалить конечный пробел в конце, используйте заглядываниетоже:

(^\d{10}(?=\s)|(?<=\")\d{10}(?=\"))
0 голосов
/ 28 декабря 2018

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

^\d{10}(?=\s)|(?<=")\d{10}(?=")

См. Демонстрацию regex .

В Python объявите его как

rx = r'^\d{10}(?=\s)|(?<=")\d{10}(?=")'

Детали шаблона

  • ^\d{10}(?=\s):
    • ^ - начало строки
    • \d{10}- десять цифр
    • (?=\s) - положительный прогноз, требующий символа пробела непосредственно справа от текущего местоположения
  • | - или
  • (?<=")\d{10}(?="):
    • (?<=") - " символ
    • \d{10} - десять цифр
    • (?=") - положительный прогноз, требующий двойногокавычка справа от текущего местоположения.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...