Правильные регулярные выражения для соответствия дате - PullRequest
0 голосов
/ 28 октября 2009

Какое правильное регулярное выражение использовать для проверки даты как. 2009-10-22 или 2009-01-01 и т. Д. Платформа PHP

Ответы [ 11 ]

7 голосов
/ 28 октября 2009

Этот (из regexplib.com ) будет соответствовать тому, что вы хотите, и выполнять проверки для високосных годов, дней в месяце и т. Д. Он немного более терпим к разделителям, чем Вы хотите, но это можно легко исправить. Как видите, это довольно отвратительно.

В качестве альтернативы (и, на мой взгляд, желательно), вы можете просто проверить цифры в правильных местах, а затем выполнить код високосного года и числа дней в месяце. Иногда одно регулярное выражение не так понятно, и есть большая ясность в явном выполнении проверок в коде (поскольку вы можете точно сообщить, что не так - «только 30 дней в ноябре», а не сообщение «не соответствует шаблону», что рядом бесполезно)

3 голосов
/ 28 октября 2009

Если вы хотите что-то простое, которое делает чуть больше, чем просто проверяет формат, но не идет так далеко, как проверка количества дней в введенном месяце или високосных лет, вы можете использовать это:

^(19|20)[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$

В этом примере допускаются годы 19xx и 20xx

1 голос
/ 28 октября 2009

ОК, регулярное выражение, которое будет проверять месячные и дневные диапазоны, может быть

[0-9]{4}-(?:1[0-2]|[1-9])-(?:3[01]|[12][0-9]|[1-9])

Если вы хотите ограничить годы, скажем, с 1900 по 2050 год, вы можете получить

(?:2050|20[0-4][0-9]|19[0-9]{2})-(?:1[0-2]|[1-9])-(?:3[01]|[12][0-9]|[1-9])

Они не будут отлавливать «слегка неправильные» даты, такие как 31 февраля, поэтому на самом деле совершенно ясно, что проверку работоспособности необходимо выполнять вне регулярного выражения.

1 голос
/ 28 октября 2009

обнаружил это в сети, проверил его с несколькими датами и выглядит стабильным, для дат между 1900 и 2000:

(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])
1 голос
/ 28 октября 2009

\d{4}-\d{2}-\d{2} будет соответствовать строке в этой форме, но чтобы проверить, является ли дата действительной, вам нужно разбить эту строку на части года, месяца и даты (вы можете использовать это регулярное выражение для этого) и проверить каждую из них .

Вы можете дополнительно убедиться, что год должен начинаться с 1 или 2: [12]\d{3}-\d{2}-\d{2}, и вы также можете сделать то же самое для месяца и дня: [12]\d{3}-[01]\d-[0123]\d (но я бы пошел с первым регулярным выражением и сравнил части " вручную ")

1 голос
/ 28 октября 2009

Поскольку вам приходится иметь дело с принятием 2009-02-28, но не с 2009-02-29, а с принятием 2008-02-28, вам нужно больше логики, чем я думаю, может дать регулярное выражение. (Но если кто-то может показать это, я был бы впечатлен)

Я бы попытался преобразовать ее в дату и сообщить, если преобразование не удалось или если у вас на вашем языке есть функция проверки даты, используйте это.

0 голосов
/ 28 октября 2009

Если вы можете полагаться не только на регулярные выражения, то гибридное решение с использованием функций posix date () и time (), поставляемых с PHP, может выглядеть следующим образом:

<?php
date_default_timezone_set("GMT");

function validateDate($date)
{
    if (preg_match("^[0-9]{4}-[0-9]{2}-[0-9]{2}^", $date))
    {
        return date('Y-m-d', strtotime($date)) === $date;
    }
    return false;
}

// Some tests
$dates = array(
    '2009-09-09', '2009-09-32', '2009-31-00', '2035-01-02',
);
foreach($dates AS $date)
{
    echo $date .': '. (validateDate($date) ? 'OK' : 'FAILS') ."\n";
}
?>

Это не элегантно, плюс вы будете ограничены временем Unix Epoch (с 1 января 1970 г. 00:00:00 по Гринвичу до 19 января 2038 03:14:07 по Гринвичу), но это надежно и хорошо поддерживается в PHP.

0 голосов
/ 28 октября 2009

Для полной проверки (которая включала бы проверку того, что части дня, месяца и года действительны), Regex не является инструментом выбора. Помимо проблем с месяцами у вас бывают проблемы с високосными годами ...

Так что, если вы просто хотите проверить, является ли приблизительный формат правильным, или изолировать разные части (год-месяц-день), регулярное выражение подходит.

([0-9]{1,4})-(1[012]|0?[1-9])-([12][0-9]|3[01]|0?[1-9])

Это уже довольно точно и включает год (0..9999), месяц и день в группы захвата, готовые к анализу ...

0 голосов
/ 28 октября 2009
 ^\d{4}-\d{2}-\d{2}$

но никакое регулярное выражение не может помешать кому-либо ввести "9867-39-56"

0 голосов
/ 28 октября 2009
[0-9]{4}-[0-9]{2}-[0-9]{2}

или

\d\d\d\d-\d\d-\d\d

или

...

просто прочитайте первый учебник по регулярным выражениям

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