Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Регулярные выражения. Тренировки teddy [2]
Форумы портала PHP.SU » PHP » Регулярные выражения » Регулярные выражения. Тренировки teddy

Страниц (3): « 1 [2] 3 »
 

16. teddy - 18 Августа, 2013 - 01:14:44 - перейти к сообщению
Экранирование помогло, спасибо ) я думал оно только внутри скобок []() требуется...

Саныч пишет:
Учитывайте допустимые значения в самой регулярке.

А как узнать что то или иное значение больше 254 если не через проверку элементов массива?
17. DelphinPRO - 18 Августа, 2013 - 01:16:16 - перейти к сообщению
Задача - спарсить стандартный html-тег (для упрощения - только парный). Получить на выходе имя тега, массив атрибутов и их значений (учесть что атрибут может не иметь значения) и текстовое содежимое самого тега. Вложенных тегов нет.
Практическая ценность стремится к нулю, но для обучения пойдет.
18. Саныч - 18 Августа, 2013 - 01:16:29 - перейти к сообщению
teddy пишет:
А как узнать что то или иное значение больше 254 если не через проверку элементов массива?
А никак. Просто саму регулярку составляйте так, чтобы под нее попали только нужные диапазоны цифр.

Да и почему 254, а не 255?..
19. teddy - 18 Августа, 2013 - 01:22:22 - перейти к сообщению
DelphinPRO
Спасибо, но уже днем наверное Улыбка

Саныч пишет:
Просто саму регулярку составляйте так, чтобы под нее попали только нужные диапазоны цифр.

Учту, спасибо ) Сейчас наверное отправлюсь отдыхать, но завтра начну снова курить это дело...
(Добавление)
Саныч
Что то сон отогнала мне ваша регулярка... я вот все понять ее до конца не могу...
Ща напишу как я её понимаю
CODE (html):
скопировать код в буфер обмена
  1. #^(?:\d{1,3}(?:\.|$)){4}$#

^ - начало строки(начинаться выражение может в данном случае только с того что в главных скобках

далее идет комбинация ?: которая в моем понимании означает - все что идет после двоеточия будет выброшено из $ip, но там \d который пропускает цифры(вроде должно срезаться) а они почему то попадают под шаблон. {1, 3} понятно, минимум одна цифра, максимум

3. Далее снова ступор с ?: \.(экранированная точка) и вроде тоже должна быть исключена. и что означает эта волшебная палочка | - я вообще без понятия Недовольство, огорчение {4} - не менее и не более 4 кармашков скажем так... т.е 127.0.0.1 $ - конец строки.

Вообщем думаю я заблуждаюсь по поводу ?: - если да то поправьте пожалуйста. И ещё не понял того, как данная регулярка определяет что нельзя более 255 писать в каждый кармашек... секрет в "палочке"? ))

Вообщем бардак в голове )
20. Саныч - 18 Августа, 2013 - 02:54:33 - перейти к сообщению
teddy, постараюсь пояснить. Да кстати, я там обновил свой ответ, последнего символа $ нет теперь, но это не принципиально, разницы никакой, просто дублирование получалось.

Теперь по порядку.

Символы ^ и $ - это начало и конец строки соответственно. Где бы они ни были, хоть в символьно классе (в квадратных скобках), хоть еще где. Если нет экранирования - это спец символы. Также как и точка, ну вы с ней уже разобрались Улыбка Есть только одно исключение для символа ^, когда он не значит "начало строки", но пока опустим этот момент.

Комбинация ?: - это группировка без обратной связи. Ставится сразу после открывающейся круглой скобки. Используется если нам не нужно нигде использовать часть заключенную в этой скобке. Т.е. если идет просто группировка (просто круглые скобки), то значение, что в них попадет будет запомнено и доступно после. Это как вы проверяли части IP в своем варинте в цикле. Т.е. у вас после preg_match был массив с частями исходной строки. А вот если указать ?:, то этих частей уже не будет. Надеюсь ясно объянил. Зачем это нужно? Не занимает память, соответственно ускорение работы. С регулярками это вобще критично, т.к. они сами по себе достаточно медленные.

"волшебная палочка |" означает "или". Т.е. в моем случае выражение (?:\.|$) значит следующее: символ точка или конец стоки.

Чтоб еще понятней стало опишу, как я составлял эту регулярку по шагам.
1. Вся строка это ip адресс, т.е. от начала до конца. ок, пишем
2. Строка состоит строго из четырех одинаковых частей (четыре части разделеных точкой). ок, пишем дальше
3. каждая часть может быть от одной до трех цифр. так и запишем
CODE (htmlphp):
скопировать код в буфер обмена
  1. '#^(?:\d{1,3}){4}$#'
4. после каждой группы цифр обязательно должна стоять точка, но кроме последней группы, после нее должен быть конец строки, т.е. имеем: символ точка или конец строки, записываем
CODE (htmlphp):
скопировать код в буфер обмена
  1. '#^(?:\d{1,3}(?:\.|$)){4}$#'
5. и последнее, конец строки мы уже проконтролировали, удаляем последний символ. Окончательный вариант
CODE (htmlphp):
скопировать код в буфер обмена
  1. '#^(?:\d{1,3}(?:\.|$)){4}#'

Вот так вот, простое разбиение на мельчайшие блоки, простая логика, по шажочкам и получилась эта страшная строка Улыбка

teddy пишет:
И ещё не понял того, как данная регулярка определяет что нельзя более 255 писать в каждый кармашек
Никак не определяет Улыбка Это ведь был ответ к первому заданию. Ответ ко второму пока не выкладываю, попробуйте сами решить. Дам только небольшую подсказку, изменить нужно только вот эту часть \d{1,3}
По длине же новая регулярка у меня получилась примерно раза в два больше.
21. EuGen - 18 Августа, 2013 - 11:10:10 - перейти к сообщению
Как проверить на соответствие диапазону - см. здесь. (применить аргументы 0, 254 и увидеть результирующее выражение)
Ответ на то, почему 254, а не 255 - рекомендую почитать про адреса подсетей и CIDR-спецификацию.
22. teddy - 18 Августа, 2013 - 14:57:01 - перейти к сообщению
Саныч пишет:
Есть только одно исключение для символа ^, когда он не значит "начало строки", но пока опустим этот момент.

Я знаю Улыбка это когда он внутри класса [] тогда меняется смысл

В принципе понятно, я просто на ночь глядя тупанул, записал такой "айпишник" 999.999.999.999 и увидел что фильтр оно не прошло. Вот сегодня посмотрел ещё раз, оказывается я не туда смотрел, а смотрел там где я циклом проверял максимальное значение Улыбка Поэтому думал, что ваша регулярка отбрасывает все числа больше 255 вот и не понимал как ) Спасибо Саныч

И ещё понял что один и тот же результат можно получить разными вариантами. А до этого думал с регулярками все по строжеУлыбка а оказался бардак ))

EuGen
Спасибо за рекомендацию, а класс интересный сам по себе, но чем к примеру плохо то как выполнил я следующее задание? т.е разбил каждую часть выражения(айпи) на ячейку массива $matches а потом в цикле прошелся по его элементам и если какой то из элементов больше чем то что нам нужно - получаем ошибку... Итераций тоже не много, максимум 4

Следующее буду выполнять последнее задание от EuGen и DelphinPRO
23. EuGen - 18 Августа, 2013 - 15:06:47 - перейти к сообщению
Решение не плохо, оно просто не отвечает изначальной задаче - написать регулярное выражение.
24. teddy - 18 Августа, 2013 - 15:08:32 - перейти к сообщению
EuGen
а-а теперь понятно, просто я изначально думал, что тут можно обойтись без имитирования собственных символов для регулярного выражения
25. EuGen - 18 Августа, 2013 - 15:46:54 - перейти к сообщению
Верно. Тем временем, поскольку нужно усложнять задачи (оставляя их при том нужными, то есть реально возникающими на практике), напишите выражение ля проверки сложности пароля. Пароль должен:
* Не быть короче 6 символов
* Должен содержать хотя бы одну прописную букву
* Должен содержать хотя бы одну заглавную букву
* Не должен содержать идущие подряд коследовательности из 3 и более символов на клавиатуре (то есть, подстрока "qwerty" недопустима - 5 подряд символов в линию, начиная с символа "q", но "qw" - допустимо, так как менее 3-х символов
* Не должен содержать идущие подряд коследовательности из 3 и более символов в алфавитном порядке (то есть, подстрока "abcdef" - 5 подряд символов в алфавитном порядке, начиная с символа "a", но "cd" - допустимо, так как менее 3-х символов)
* Должен содержать хотя бы один специальный символ
26. teddy - 18 Августа, 2013 - 16:07:51 - перейти к сообщению
EuGen
Ого, очень интересная задача, спасибо Улыбка Займусь обязательно
27. Саныч - 19 Августа, 2013 - 00:01:03 - перейти к сообщению
teddy, ответ к второй задаче об IP
PHP:
скопировать код в буфер обмена
  1. '#^(?:(?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])(?:\.|$)){4}#'


EuGen, смотрел ваш класс. Конечно за труд вам +1, но регулярку он выдает очень большую, совсем не красивую... А на больших числах (4 и более разрядов) это особенно заметно.
Пытался сегодня написать аналог, но по-лучше. Вобщем идеала мне добится так и не удалось... Да и практической пользы от этого я не вижу. В итоге забросил эту затею.
28. teddy - 19 Августа, 2013 - 13:53:39 - перейти к сообщению
Блин вообще ничего не получается Хм Все задания путаются в одной точке... Попробую объяснить хоть как то в чем проблема

Например возьмем задание от EuGen про пароли.

Пытался написать только первую часть
$password = "Hello";
PHP:
скопировать код в буфер обмена
  1. if(!preg_match("/([a-z]{1,})?([A-Z]{1,})+/", $password, $matches)){
  2.     echo "!Matches";
  3.        
  4. }else{
  5.     echo "ОК";
  6. }
  7.  

hello - бракует
Hello - норм(есть хотя бы одна большая и маленькая буква)
но HELLO - тоже пропускает. а ведь маленькой буквы нет. Потяное дело что у меня стоит ? который говорит либо 0 либо одно совпадение. Но если влепить + то результат от этого не меняется...

Не пойму в чем загвоздка и когда берусь делать другие задания на выходе получаю такой же бред...
Пробовал брать всё в одни большие скобки и перед ними ставить ^ - что то все что в скобках - с того может и должна начинаться строка...

Вообщем ступор сердитый..

Например запретить qwerty планируют запретить следующим образом [^qwerty] (крышка внутри класса) но как дать понять что это одна строка и все эти символы могут встречаться где угодно - не понятно.. я ж не указывал начало строки
29. Саныч - 19 Августа, 2013 - 14:21:19 - перейти к сообщению
У меня как-то так получилось. Сейсас проверяет длину всейго пароля, минимум одна заглавная, минимум одна строчная буква, минимум один символ.
PHP:
скопировать код в буфер обмена
  1. $match = preg_match('#^(?:([a-z])|([A-Z])|([`~!@\#№$%^&*()\-_=+{}\[\];:|<>,\.?/])|.){6,}$#', $str, $matches);
  2. if ($match && !empty($matches[1]) && !empty($matches[2]) && !empty($matches[3])) {
  3.     echo 'valid';
  4. } else {
  5.     echo 'invalid';
  6. }


Хотя как по мне, регулярка тут вобще не нужна. Проще разбить строку на символы, а дальше уже по кодам символов посмотреть...
(Добавление)
teddy пишет:
планируют запретить следующим образом [^qwerty]
Не пойдет. Это значит: любой символ, кроме символов qwerty. К примеру строка test под этот шаблон уже не попадет, т.е. будет считаться невалидной
30. Panoptik - 19 Августа, 2013 - 14:28:23 - перейти к сообщению
ну а как быть с последовательностями?

если последовательности ограничиваются началом с символами asdf || qwer || abcde

то есть регулярка примерно такая?


или же нужно проверять и такие как sdfg || werty || bcdef ?

 

Powered by ExBB FM 1.0 RC1