Не давно меня заинтересовал вопрос как сделать регулярное выражение для проверки диапазона чисел а конкретно года, текущий год - 100 до текущий год - 16. Я начал сначала пробовать строить простые выражения: (0[0-9]|1[0-2]) - 01-12, потом по сложнее (0[1-9]|[1-2][0-9]|3[01]) - 01-31, ну и наконец дело дошло до года (191[6-9]|19[2-9][0-9]|2000) - 1916 - 2000, когда я понял что у меня не получиться сделать подобное на основе текущей даты, а каждый год менять регулярку на новую как то не прикалывает. Я написал php функцию которая создаёт регулярку для диапазона чисел: Код (PHP): /** * Формирует регулярное выражение * для диапазона чисел * * @param $start - Начальное число * @param $finish - Конечное число * @param bool $zero - Нужен ведущий ноль? 04 или 4? * @return false|string */ function rangeRegex($start, $finish, $zero = false) { // Если первое число больше второго // или какой то из параметров не // являеться число if($start >= $finish || ! is_int($start) || ! is_int($finish)) { return false; } $out = '('; // Цикл по диапазону чисел foreach(range($start, $finish) as $number) { // Если число меньше или // равно 9 и если надо добавляем // ведущий ноль if ($number <= 9 && $zero) { $out .= 0; } $out .= $number; // Если число не является // последним добавляем разделитель if ($number != $finish) { $out .= '|'; } } $out .= ')'; return $out; } Она делает ужасную вещь генерирует все возможные варианты чисел и перечисляет их через |. Начал проверять работу функции: Код (PHP): rangeRegex(1, 12, true);// (01|02|03|04|05|06|07|08|09|10|11|12) rangeRegex(1, 31, true);// (01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31) rangeRegex(((int) date('Y')) - 100, ((int) date('Y')) - 16);// o_O Насколько правильный такой подход? И как можно по другому сделать диапазон от ((int) date('Y'))-100 до (int) date('Y'))-16?
регулярка не предназначена для подобных действий. прими это и прости. проверяй обычным способом, как выражение с больше-меньше.
я както давно в академических целях писал такую универсальную регулярку) получилась большая, но универсальная, для всех чисел года, кроме 29 февраля. ибо тут нужна информация о високостности года. а это уже усложняет регулярку неимоверно.
вспомнил. вот что получилось тогда, для формата DD-MM-YYYY для дат от 2000 года Код (PHP): /^((0[1-9]|[12]\d)-(0[1-9]|1[012])|30-(0[13-9]|1[012])|31-(0[13578]|1[02]))-2\d{3}$/ Добавлено спустя 4 минуты 32 секунды:еще для проверки даты можно юзать checkdate()
Вот мой вариант по сложнее работает с любой датой в диапазоне 1900-2100, и с високосными годами, формат YYYY-MM-DD: Код (PHP): /^(190[48]|(19|20)[13579][26]|19[2468][048]|20[02468][048])-((0[12478]|(10|12))-(0[1-9]|[12][0-9]|3[01])|(02)-(0[1-9]|[12][0-9])|(0[469]|11)-(0[1-9]|[12][0-9]|30))|(19[0-9][0-9]|20[0-9][0-9]|2100)-((0[12478]|10)-(0[1-9]|[12][0-9]|3[01])|(02)-(0[1-9]|[12][0-9])|(0[469]|1[12])-(0[1-9]|[12][0-9]|30))$/ Ладно шучу))) Вот вариант с табуляцей: Код (PHP): /^ ( (?# Високосные года) 190[48] | (19|20)[13579][26] | 19[2468][048] | 20[02468][048] )-( ( (?# Месяцы 1, 2, 4, 7, 8, 10, 12) 0[12478] | (10|12) )-( (?# 31 день) 0[1-9] | [12][0-9] | 3[01] ) | ( (?# Февраль) 02 )-( (?# 29 дней) 0[1-9] | [12][0-9] ) | ( (?# Месяцы 4, 6, 9, 11) 0[469] | 11 )-( (?# 30 дней) 0[1-9] | [12][0-9] | 30 ) ) | ( (?# Все года в диапозоне 1900-2100) 19[0-9][0-9] | 20[0-9][0-9] | 2100 )-( ( (?# Месяцы 1, 2, 4, 7, 8, 10) 0[12478] | 10 )-( (?# 31 день) 0[1-9] | [12][0-9] | 3[01] ) | ( (?# Февраль) 02 )-( (?# 29 Дней) 0[1-9] | [12][0-9] ) | ( (?# Месяцы 4, 6, 9, 11, 12) 0[469] | 1[12] )-( (?# 30 дней) 0[1-9] | [12][0-9] | 30 ) ) $/