Получить дату из замусоренной строки
К примеру есть замусоренная строка: 69qw15_2223фупянваря 2021 года 222023
Понятно что тут не угадать какой день, но пусть будут 2 рядом стоящие цифры (если есть) перед месяцем. Т.е. день может быть 1, 2, 08, 22 и т.д.
.*([0-3]?[0-9]{1}).*(января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря){1}.*?(20[0-9]?[0-9]?)
https://regex101.com/r/aYzQiE/1
Но в таком случае не вытягивается первая цифра дня. Результат:
группа 1 3
группа 2 января
группа 3 2021
Как записать первую группу так, чтобы все же получить в данном случае 23 день?
Ответы (1 шт):
Во-первых, существующий формат данных разрешает дни месяца 0, 32..39, и его следует исправить: (0?[1-9]|[1-2][0-9]|3[01])
Во-вторых, "жадный" префикс .* проглотит все символы до цифры, включая и опциональную первую цифру [0-3]?, причём сделает это не слишком эффективно.
Для поиска ближайшей корректной даты перед названием месяца нужно применить конструкцию, включающую негативный lookahead: ДАТА(Не-ДАТА)*МЕСЯЦ, тогда полное регулярное выражение выглядит так:
(0?[1-9]|[1-2][0-9]|3[01])(?:(?!0?[1-9]|[1-2][0-9]|3[01]).)*(января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря).*?(20[0-9]?[0-9]?)
69qw15_03фупянваря 2021 года 222023
Match information
Match 1 7-26 03фупянваря 2021
Group 1 7-9 03
Group 2 12-18 января
Group 3 22-26 2021
Однако, в случае дублированного названия месяца данная регулярка выбирает название последнего подходящего месяца. Поэтому может понадобиться внести условие (?:(?!ДАТА|МЕСЯЦ).)*, чтобы выбирался первый месяц:
Онлайн-демо
69qw15_03фупянваря марта 2021 года 222023
Match information
Match 1 7-31 03фупянваря марта 2021
Group 1 7-9 03
Group 2 12-18 января
Group 3 22-26 2021