Шаблон американского времени (perl)
Пытаюсь написать шаблон - не получается.
По условию под этот шаблон должны подходить 12:00am, 5:00pm и 8:30AM. Не должны подходить: 3:00, 2:60am, 99:00am, 3:0pm.
Получилось:
Как указать, что первая цифра ([0-1]) необязательна? Пробовал "?", "*" и что-то ещё. Не помогает. Сколько литературы по шаблонам не просмотрел, везде описывается одно и тоже (ограниченно как-то).
Оно?
надо бы наверно (am|pm) поставить
И да и нет. Уже пробовал такой вариант. По спецификации должен работать, но не работает. Под данный шаблон подходит как 5:00pm, так и 99:00am. А ведь такго быть не должно. :(
надо бы наверно (am|pm) поставить
Действительно. Что-то не думал над этим. :-) Однако тоже не работает. 0_о Принимается как pa, так ma и mp. Странно... Может, ActivePerl того этого? Шутит?
m/[0-1]{0,1}[0-9]{1}:[0-5][0-9][pma]{2}/i
хотя думаю так лучше:
m/[0-1]{0,1}[0-9]{1}:[0-4]{0,1}[0-9]{1}(pm|am)/i
а?
Да нет, литература нормальная есть. В манах кстати очень неплохо изложено. Хотя еще лучше написано вот тут: Регулярные выражения.
А регулярка долна быть в духе:
$str = '12:00am';
$a = preg_match('/^[0-1]?[0-9]:[0-5][0-9](am|pm)$/i',$str);
if ($a == 1)
{
echo 'Строка '.$str.' проходит<br>';
}
else
{
echo 'Строка '.$str.' НЕ проходит<br>';
};
$str = '5:00pm';
$a = preg_match('/^[0-1]?[0-9]:[0-5][0-9](am|pm)$/i',$str);
if ($a == 1)
{
echo 'Строка '.$str.' проходит<br>';
}
else
{
echo 'Строка '.$str.' НЕ проходит<br>';
};
$str = '8:30AM';
$a = preg_match('/^[0-1]?[0-9]:[0-5][0-9](am|pm)$/i',$str);
if ($a == 1)
{
echo 'Строка '.$str.' проходит<br>';
}
else
{
echo 'Строка '.$str.' НЕ проходит<br>';
};
$str = '3:00';
$a = preg_match('/^[0-1]?[0-9]:[0-5][0-9](am|pm)$/i',$str);
if ($a == 1)
{
echo 'Строка '.$str.' проходит<br>';
}
else
{
echo 'Строка '.$str.' НЕ проходит<br>';
};
$str = '2:60am';
$a = preg_match('/^[0-1]?[0-9]:[0-5][0-9](am|pm)$/i',$str);
if ($a == 1)
{
echo 'Строка '.$str.' проходит<br>';
}
else
{
echo 'Строка '.$str.' НЕ проходит<br>';
};
$str = '99:00am';
$a = preg_match('/^[0-1]?[0-9]:[0-5][0-9](am|pm)$/i',$str);
if ($a == 1)
{
echo 'Строка '.$str.' проходит<br>';
}
else
{
echo 'Строка '.$str.' НЕ проходит<br>';
};
$str = '3:0pm';
$a = preg_match('/^[0-1]?[0-9]:[0-5][0-9](am|pm)$/i',$str);
if ($a == 1)
{
echo 'Строка '.$str.' проходит<br>';
}
else
{
echo 'Строка '.$str.' НЕ проходит<br>';
};
?>
m/[0-1]{0,1}[0-9]{1}:[0-5][0-9][pma]{2}/i
хотя думаю так лучше:
m/[0-1]{0,1}[0-9]{1}:[0-4]{0,1}[0-9]{1}(pm|am)/i
а?
[0-1]{0,1} и [0-1]? эквивалентны, но второй более предпочтителен, т.к более короток.
[0-9]{1} и [0-9] эквивалентны, но.... опять же более коротная запись.
m/[0-1]{0,1}[0-9]{1}:[0-5][0-9][pma]{2}/i
хотя думаю так лучше:
m/[0-1]{0,1}[0-9]{1}:[0-4]{0,1}[0-9]{1}(pm|am)/i
а?
Разве указание [0-9] не равносильно [0-9]{1} ?
Мануал, конечно, хорошая литература, но тяжеловата. За ссылку спасибо, почитаю.
Этот шаблон подходит по всем условиям: m/^[0-1]?[[0-9]:[0-5][0-9][am|pm]{2}/i !
Всем спасибо!
Этот шаблон подходит по всем условиям: m/^[0-1]?[[0-9]:[0-5][0-9][am|pm]{2}/i !
Странный шаблон в контексте PHP... но видимо на Perl он катит...
Проверял и на php и на perl - работает везде. Признаться честно самому странным кажется. Хотя, скорее всего ещё не до конца понял правила использования специальных символов.
Странный тогда у тебя PHP. У меня 5.2 ругается на модификатор m проставленный в начале выражения:
Warning: preg_match() [function.preg-match.html]: Delimiter must not be alphanumeric or backslash in H:\web\test\test_script1.php on line 3
Если поставить вконце то все ок.
А смысла в открытии символьного класса и не закрытие я вообще не понял.
/^[0-1]?[COLOR="Red"][[/COLOR][0-9]:[0-5][0-9][am|pm]{2}/im
В остально же практически тот же шаблон, что я уже писал.
а хорошая книга по регулярным выражениям есть. называется она "Регулярные выражения. Библиотека программиста". Написана - Джеффри Фриделем. Это лучшая существующая книга по регекспам. Ценность ее еще и в том, что она не привязана к языку.
Уверен? Мне скрипт вот что написал:
Строка 19:00 НЕ проходит
словами запиши то, что написал:
[0-1]?[0-9]:[0-5][0-9](am|pm)
0 или 1 или ничего, затем цифра от 0 до 9, затем двоеточие, затем цифра от 0 до 5, затем цифра от 0 до 9, после чего либо am либо pm.
19:00am - подходит. условию задачи такое решение не удовлетворяет.
Ах вот ты очем.. так и для твоей регулярки пройдет.
либо
в зависимости от ситуации, будут более правильными вариантами.
в любом случае - 19:00am в моем случае совпадало не потому, что регулярка совпадает с неправильным куском текста, как в твоем случае. совпадение происходит с 9:00am.
У меня версия 4.4 ипсользую PHP Expert Editor - ошибок нет.
/^[0-1]?[COLOR="Red"][[/COLOR][0-9]:[0-5][0-9][am|pm]{2}/im
В остально же практически тот же шаблон, что я уже писал.
Извиняюсь, опечатка. :-)
Это он и есть.
Просто упустил. :-) Спасибо за уточнение столь важного момента.
Спасибо. Уже просматриваю.
Только символ "?" в данном шаблоне, по-моему, лишний. Опечатка?
в зависимости от ситуации, будут более правильными вариантами.
03:00am не продет, хотя и должен. Сдается мне что тут шаблон-утверждение нужно использовать. И окончательно правильный шаблон будет:
[LEFT]/\b(1[012]|0?[1-9]):[0-5][0-9]?(am|pm)\b/i
плюс - в этом варианте не прокатит 00:00. можно изменить так:
[LEFT]/\b(1[012]|0?[1-9]|00?):[0-5][0-9]?(am|pm)\b/i
можно еще подрихтовать, чтобы 00:00 выводилось без am/pm (ибо тупо :) )[/LEFT]
[/LEFT]
Понятно, не знал.