Обновление. В настоящее время достигнуто рабочее решение с использованием нескольких регулярных выражений одновременно
Я ищу регулярное выражение, которое охватывает диапазон приемлемого синтаксиса для дат ISO 8601. Большинство библиотек и регулярных выражений охватывают только подмножество или «упрощенную» версию 8601, такую как RFC 3339, но полный 8601 включает способы выражения продолжительности времени и интервалов. Запись в Википедии для ISO 8601 дает хороший обзор, но вкратце все они должны быть действительными датами:
var testDates = {
'year' : "2013",
'date' : "2013-01-05",
'datetime' : "2013-01-05T04:13:00+00:00",
'Duration only' : "P1Y2M10DT2H30M",
'Week Duration' : "P1W",
'Range with start and end' : "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z",
'Range of Date/Duration' : "2007-03-01T13:00:00Z/P1Y2M10DT2H30M",
'Range of Date/Duration 1 month' : "2012-10/P1M",
'Range of Date/Duration 1 week' : "2012-10/P1W",
'Range of Duration/Date' : "P1Y2M10DT2H30M/2007-03-01T13:00:00Z",
'Repeating interval 5 times' : "R5/2007-03-01T13:00:00Z/P1Y2M10DT2H30M",
'Repeating interval weekly indefinitely' : "R/2012-10/P1W",
'Repeating interval monthly 5 times' : "R5/2012-10/P1M"
}
Я пытаюсь создать регулярное выражение, которое будет охватывать все эти возможности. Я собрал несколько компонентов вместе, но недостаточно хорошо разбираюсь в регулярных выражениях, чтобы все они работали как одно выражение и охватывали все возможные случаи. Простое выполнение простого «ИЛИ» между ними, похоже, не работает должным образом, но, возможно, я делаю это не совсем правильно.
Выражения, которые я пробовал, включают следующее:
var regex = {
'Date' : /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/,
'Duration' : /^P(?=\w*\d)(?:\d+Y|Y)?(?:\d+M|M)?(?:\d+W|W)?(?:\d+D|D)?(?:T(?:\d+H|H)?(?:\d+M|M)?(?:\d+(?:\.\d{1,2})?S|S)?)?$/,
'Range of Date/Date' : /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?(\/)([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/,
'Range of Date/Duration' : /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?(\/)P(?=\w*\d)(?:\d+Y|Y)?(?:\d+M|M)?(?:\d+W|W)?(?:\d+D|D)?(?:T(?:\d+H|H)?(?:\d+M|M)?(?:\d+(?:\.\d{1,2})?S|S)?)?$/,
'Range of Duration/Date' : /^P(?=\w*\d)(?:\d+Y|Y)?(?:\d+M|M)?(?:\d+W|W)?(?:\d+D|D)?(?:T(?:\d+H|H)?(?:\d+M|M)?(?:\d+(?:\.\d{1,2})?S|S)?)?\/([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/,
'Repeating interval' : /^R\d*\/([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?\/P(?=\w*\d)(?:\d+Y|Y)?(?:\d+M|M)?(?:\d+W|W)?(?:\d+D|D)?(?:T(?:\d+H|H)?(?:\d+M|M)?(?:\d+(?:\.\d{1,2})?S|S)?)?$/
}
Я собрал пример сценария, который пробует эти выражения в каждую из дат, перечисленных выше, но если кто-нибудь может дать рекомендации по объединению всех этих случаев в одно выражение, я был бы очень признателен.
Вариант использования, который приводит к этому, заключается в проверке даты ISO 8601 для документа схемы JSON. Схема JSON обеспечивает некоторую гибкость в том, как что-то проверяется, поскольку вы можете предоставить несколько правил или регулярных выражений для тестирования. В этом случае я мог бы решить свою проблему, используя несколько регулярных выражений, а не одно комбинированное выражение.
Обновление: до сих пор проблема решалась с помощью этого подхода (одновременное использование нескольких отдельных выражений).
Вот сценарий:
- Вкратце: https://gist.github.com/philipashlock/8830168
- В качестве веб-страницы: http://bl.ocks.org/philipashlock/raw/8830168/ а>