#regex #date
#регулярное выражение #Дата
Вопрос:
Я пишу регулярное выражение для захвата различных форматов даты. Чтобы сделать его коротким и гибким, я хотел упаковать все возможные комбинации месяцев, дней и лет в отдельные группы. Предположим, у меня есть две такие даты:
01.01. — 31.12.2013
январь — декабрь 2013
Теперь, чего я хочу добиться, это написать регулярное выражение, которое будет фиксировать обе даты, подобные указанным выше. это просто. но я также хочу исключить такие даты, как, например, те:
01.01. — 31 декабря 2013
Другими словами, всякий раз, когда месяцы смешиваются, мне не нужны эти даты. Кроме того, если у первой даты нет дня, я не хочу, чтобы этот день был записан и во второй.
Я хотел создать условие, которое фиксирует только соответствующие поля второй даты, основываясь на том, что найдено в первом (так, например, если первая дата имеет альфа-месяц, ищите только альфа-месяц во втором, игнорируйте числовой). Мое регулярное выражение выглядит так:
(?<firstDay>0[1-9]|[12][0-9]|3[01]|[1-9])[-/s.](?<firstMonth>0[1-9]|1[012]|[p{L}]{3,}|[1-9])s*[-s/.]*s*(?<secondDay>0[1-9]|[12][0-9]|3[01]|[1-9])[-s/.]*(?<secondMonth>((?<firstMonth>)(?<=0[1-9]|1[012]|[1-9]))(0[1-9]|1[012]|[1-9])|[p{L}]{3,})[-s/.]*(?<year>(19|20)dd|[012][0-9]$)
Это все предыстория, но мой вопрос в том, можно ли проверить, чему равна захваченная группа, и на основе этого создать условие захвата?Я нашел похожую тему о переполнении стека (к сожалению, не могу найти ее сейчас для ссылки), но когда я ее реализую, она перестает фиксировать некоторые правильные даты (например, 01.01. — 31.12.2013). Это та часть:
(?<secondMonth>((?<firstMonth>)(?<=0[1-9]|1[012]|[1-9]))(0[1-9]|1[012]|[1-9])|[p{L}]{3,})
Комментарии:
1. Какой тип регулярных выражений вы используете? Какой язык? Например, Perl имеет такой приятный синтаксис:
(?(condition)yes-pattern|no-pattern)
2. Я делаю это на C #. Синтаксис, который вы предлагаете, в порядке, но как мне написать часть «условие»? Я знаю только о возможности проверить, идентифицирована ли группа или нет, но не о том, какое значение она принимает.
3. .Net поддерживает этот синтаксис, так что все в порядке. Я не до конца обдумал это, поскольку не дал полного ответа, но вы могли бы поместить каждую альтернативу в группе
firstMonth
захвата в свою собственную группу захвата, таким образом, вы можете узнать, какая альтернатива соответствует.(?<firstMonth>(?<firstMonthNumeric>...)|(?<firstMonthName>...))
4. Вторая мысль: я думаю, вы должны сопоставлять все свободно, используя регулярные выражения, а затем отфильтровывать плохие результаты в коде, используя
match.Groups[...]
, чтобы проверить, какая группа соответствует. Это будет намного проще.5. Нет, при разнообразии возможных форматов дат это очень негибко 🙂 Кроме того, у меня есть ссылки на именованные группы в коде C #.