Что такое шаблон RegEx для DateTime (2008-09-01 12:35:45)?
Я получаю такую ошибку:
No ending delimiter '^' found
С помощью:
preg_match('(?n:^(?=\d)((?<day>31(?!(.0?[2469]|11))|30(?!.0?2)|29(?(.0?2)(?=.{3,4}(1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|(16|[2468][048]|[3579][26])00))|0?[1-9]|1\d|2[0-8])(?<sep>[/.-])(?<month>0?[1-9]|1[012])(?<year>(1[6-9]|[2-9]\d)\d{2})(?:(?=\x20\d)\x20|$))?(?<time>((0?[1-9]|1[012])(:[0-5]\d){0,2}(?i:\ [AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$)', '2008-09-01 12:35:45');
Выдает эту ошибку:
Warning: preg_match() [function.preg-match]: Compilation failed: nothing to repeat at offset 0 in E:\www\index.php on line 19






http://regexlib.com/REDetails.aspx?regexp_id=610
^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-./])(?:1[012]|0?[1-9])(?:1[6-9]|[2-9]\d)?\d\d(?:(?=\x20\d)\x20|$))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\x20[AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$
This RE validates both dates and/or times patterns. Days in Feb. are also validated for Leap years. Dates: in dd/mm/yyyy or d/m/yy format between 1/1/1600 - 31/12/9999. Leading zeroes are optional. Date separators can be either matching dashes(-), slashes(/) or periods(.) Times: in the hh:MM:ss AM/PM 12 hour format (12:00 AM - 11:59:59 PM) or hh:MM:ss military time format (00:00:00 - 23:59:59). The 12 hour time format: 1) may have a leading zero for the hour. 2) Minutes and seconds are optional for the 12 hour format 3) AM or PM is required and case sensitive. Military time 1) must have a leading zero for all hours less than 10. 2) Minutes are manditory. 3) seconds are optional. Datetimes: combination of the above formats. A date first then a time separated by a space. ex) dd/mm/yyyy hh:MM:ss
Редактировать: убедитесь, что вы скопировали RegEx с веб-сайта regexlib.com, поскольку StackOverflow иногда удаляет / уничтожает специальные символы.
Простая версия, которая будет работать для указанного формата, но не для всех остальных согласно @Espos:
(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})
плюс одно простейшее решение!
Этот проверяет как 0000-00-00 00:00:00, так и 0000-00-00 00:00 (\ d {4}) - (\ d {2}) - (\ d {2}) (\ d { 2}): (\ d {2})? ((:)? (\ D {2}))
@Espo: Я просто должен сказать, что регулярное выражение невероятно. Мне не хотелось бы писать код, который делал бы что-то полезное с совпадениями, например, если бы вы действительно хотели узнать, какую дату и время ввел пользователь.
Похоже, что решение Тома было бы более разумным, поскольку оно примерно в миллион раз проще и с добавлением некоторых круглых скобок вы можете легко получить значения, введенные пользователем:
(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})
Если вы используете perl, вы можете получить значения примерно так:
$year = ;
$month = ;
$day = ;
$hour = ;
$minute = ;
$second = ;
Другие языки будут иметь аналогичную возможность. Обратите внимание, что вам нужно будет внести некоторые незначительные изменения в регулярное выражение, если вы хотите принимать значения, такие как однозначные месяцы.
Просто комментарий, чтобы сказать, что это регулярное выражение не определяет, имеет ли дата, месяц или время значение, превышающее максимальное. Например 2012-65-65 99:99:99 будет работать. Кроме того, регулярное выражение отличное!
Показанное регулярное выражение не предназначено для проверки даты. Он предназначен для проверки синтаксис строки, чтобы узнать, похоже ли это на дату. После получения значений вы можете проверить данную дату, используя обычные функции библиотеки дат.
Это регулярное выражение сломается через 7981 год.
Это регулярное выражение дает совпадение даже для такой даты, как 2020-99-99 99:99:99, что неверно, как упоминалось @darkheir
Функции PHP preg требуют, чтобы ваше регулярное выражение было заключено в символ-разделитель, который может быть любым символом. Вы не можете использовать этот символ-разделитель без экранирования внутри регулярного выражения. Это должно работать (здесь символ-разделитель /):
preg_match('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', '2008-09-01 12:35:45');
// or this, to allow matching 0:00:00 time too.
preg_match('/\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}/', '2008-09-01 12:35:45');
Если вам нужно сопоставить строки, содержащие только дату и время, добавьте ^ и $ в начало и конец регулярного выражения.
preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', '2008-09-01 12:35:45');
относительно ответа Имрана от 1 сентября 2008 г., 12:33 отсутствует: в шаблоне правильные шаблоны
preg_match('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', '2008-09-01 12:35:45', $m1);
print_r( $m1 );
preg_match('/\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}/', '2008-09-01 12:35:45', $m2);
print_r( $m2 );
preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', '2008-09-01 12:35:45', $m3);
print_r( $m3 );
это возвращается
Array ( [0] => 2008-09-01 12:35:45 )
Array ( [0] => 2008-09-01 12:35:45 )
Array ( [0] => 2008-09-01 12:35:45 )
^([2][0]\d{2}/([0]\d|[1][0-2])/([0-2]\d|[3][0-1]))$|^([2][0]\d{2}/([0]\d|[1][0-2])/([0-2]\d|[3][0-1])\s([0-1]\d|[2][0-3])\:[0-5]\d\:[0-5]\d)$
использовал этот с небольшой модификацией, допускающей даты до 2000 года: "^ (\ d {4} - ([0] \ d | [1] [0-2]) - ([0-2] \ d | [3] [0-1]) \ s ([0-1] \ d | [2] [0 -3]) \: [0-5] \ d \: [0-5] \ d) $ »
$date = "2014-04-01 12:00:00";
preg_match('/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/',$date, $matches);
print_r($matches);
$ совпадения будут:
Array (
[0] => 2014-04-01 12:00:00
[1] => 2014
[2] => 04
[3] => 01
[4] => 12
[5] => 00
[6] => 00
)
Простой способ разбить строку в формате datetime.
Вот упрощенная версия (полученная из ответа Эспо). Он проверяет правильность даты (даже високосный год), а чч: мм: сс является необязательным
Примеры, которые работают:
- 31 декабря 2003 г., 11:59:59
- 29-2-2004
^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-./])(?:1[012]|0?[1-9])(?:1[6-9]|[2-9]\d)?\d\d(?:(?=\x20\d)\x20|$))(|([01]\d|2[0-3])(:[0-5]\d){1,2})?$
Вот мое решение:
/^(2[0-9]{3})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]) (0[0-9]|1[0-9]|2[0123])\:([012345][0-9])\:([012345][0-9])$/u
Вот мое решение:
[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]) ([01][0-9]|2[0-3]):[0-5]\d

Я изменил шаблон регулярного выражения из http://regexlib.com/REDetails.aspx?regexp_id=610. Следующий шаблон должен соответствовать вашему случаю.
^(?=\d)(?:(?:1[6-9]|[2-9]\d)?\d\d([-./])(?:1[012]|0?[1-9])(?:31(?<!.(?:0[2469]|11))|(?:30|29)(?<!.02)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))(?:(?=\x20\d)\x20|$))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\x20[AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$
ГГГГ-ММ-ДД ЧЧ: ММ: СС
Это также соответствует ГГГГ-ММ-ДД
Добавление к ответу @Greg Hewgill: если вы хотите иметь возможность сопоставить дату и время и дату Только, вы можете сделать часть «время» в регулярном выражении необязательной:
(\d{4})-(\d{2})-(\d{2})( (\d{2}):(\d{2}):(\d{2}))?
таким образом вы будете соответствовать как 2008-09-01 12:35:42, так и 2008-09-01
Этот ответ дает хорошее регулярное выражение, но не отвечает на вопрос. Вопрос в том, чтобы проверять даты, разделенные знаком «-», а не «/», как описано в этом ответе.