Как сделать, чтобы выражения в кавычках не находились?

Рейтинг: 2Ответов: 1Опубликовано: 01.08.2023
(?:\b|\.|\s)+(d{1,4}|m{1,4}|y{4}|y{2}){1}(?:\.|\s){1}(d{1,4}|m{1,4}|y{4}|y{2})?(?:\.|\s)?(d{1,4}|m{1,4}|y{4}|y{2})?(?:\.|\s)?

https://regex101.com/r/ePV1Aq/1

Работает правильно, но находит так же совпадения внутри строк в кавычках, как это исключить? Ну и, может, красивее написать всю эту колбасу заодно. Я пробовал сокращать за счёт повторений, но тогда ломается структура (в match вся дата, в groups отдельные элементы)

Пример:

"Форматы внутри строки в кавычках DD.MM.YYYY не учитывать:" DD.MM.YYYY "и тут dd.mm тоже"

Тут мы видим 3 совпадения, нужно, чтобы находилось только второе, т.к. первое и третье находится внутри строк в кавычках ""

Ответы

▲ 1Принят

ВАЖНО!!! Подойдет скорее всего только для библиотеки PCRE


Регулярное выражение:

(?:"[^"]*"[^"]*?\K|(*SKIP))+(?(DEFINE)(?'d'd{1,4}|m{1,4}|y{2,4}))(?<![dmy.])((?P>d))\.(?!\2)((?P>d))(?:\.(?!\2|\3)((?P>d)))?(?!\.?[dmy])

Пример работы: regex101.com


Крупноблочное описание:

  • (?:"[^"]*"[^"]*?\K|(*SKIP)) - не захватываемая группа, с получением подстроки в кавычках и сбросе захвата \K, иначе не позволяем курсору вернуться к текущей позиции. Сделано для строк содержащих в себе только захватываемое поле в кавычках.
  • (?(DEFINE)(?'d'd{1,4}|m{1,4}|y{2,4})) - объявляем переменную с шаблоном для регулярного выражения, сделано что бы не писать одно и то же несколько раз а просто вызывать объявленную переменную.
  • (?<![dmy.]) - негативный просмотр назад, что бы исключить неполные совпадения (опционально).
  • ((?P>d))\.(?!\2)((?P>d)) - вызываем объявленную группу, после проверяем что не идет повторение группы, что бы исключить например MM.MM.
  • (?:\.(?!\2|\3)((?P>d)))? - необязательная группа для третьей части, но перед захватом проверяем что не было совпадения с предыдущими группами при значениях: MM.DD.MM или MM.DD.DD.