Regex - граница слова не работает даже с необработанной строкой - PullRequest
1 голос
/ 29 апреля 2020

Я кодирую набор регулярных выражений для сопоставления дат в тексте, используя python. Одно из моих регулярных выражений было разработано для сопоставления дат только в формате MM / YYYY. Регулярное выражение следующее:

r'\b((?:(?:0)[0-9])|(?:(?:1)[0-2])|(?:(?:[1-9])))(?:\/|\\)(\d{4})\b'

Похоже, что граница слова не работает, так как она соответствует частям дат, например 12/02/2020 (она не должна соответствовать этому формату даты на всех).

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

Помня, что регулярное выражение должно соответствовать шаблону MM / YYYY в таких строках, как:

"Диапазон дат go с 21/02/2020 по 21/03/2020, как указано выше. "

Можете ли вы помочь мне найти ошибку в моем шаблоне, чтобы он соответствовал только моему формату цели?

enter image description here

Ответы [ 2 ]

2 голосов
/ 29 апреля 2020

Проблема в том, что \b\d{2}/\d{4}\b соответствует 02/2000 в строке 01/02/2000, потому что первая прямая sla sh - это разрыв слова. Решение состоит в том, чтобы идентифицировать символы, которые должны , а не предшествовать и следовать за совпадением и использовать отрицательные обходные пути вместо разрывов слов. Здесь вы можете использовать регулярное выражение

r'(?<![\d/])(?:0[1-9]|1[0-2])/\d{4}(?![\d/])'

Отрицательный lookbehind , (?<![\d/]), предотвращает две цифры, представляющие месяц, перед ди git или косой чертой; отрицательный прогноз , (?![\d/]) не позволяет четырем цифрам, обозначающим год, следовать за ди git или вперед sla sh.

Regex demo

Python демо

Если необходимо сопоставить 6/2000 с 06/2000, измените (?:0[1-9] на (?:0?[1-9].

1 голос
/ 29 апреля 2020

Граница слова в большинстве диалектов регулярных выражений - это позиция между \w и \W (не состоящая из слов char) или в начале или конце строки, если она начинается или заканчивается (соответственно) словом символ ([0-9A-Za-z_]).

Что такое граница слова в регулярном выражении?

Что происходит, если символ \ не является частью группы \w, таким образом, каждый раз, когда в вашей строке появляется новая \, она считается новой границей слова.

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

^((?:(?:0)[0-9])|(?:(?:1)[0-2])|(?:(?:[1-9])))(?:\/|\\)(\d{4})$

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


edit:

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

вот новый:

(?<=^|[a-zA-Z ])(0[0-9]|1[12]|[1-9])(?:\/|\\)([\d]{4})(?=[a-zA-Z ]|$)

У меня есть заменил границу слова на lookahead (?!...) и lookbehind (?<!...), и указан шаблон, который я хочу соответствовать до и после даты. Вы можете настроить его в соответствии с вашими потребностями c и добавить другие символы, такие как цифры или данные c.

https://regex101.com/r/xncZNN/4

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