Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Проверка url
 
 автор: TetRiska   (03.02.2012 в 17:48)   письмо автору
 
 

Всем привет. Помогите исправить регулярку.
/^http:\/\/[a-z0-9\.-]{3,}\.[a-z]{2}+$/i

Нужно чтобы без http:// и в конце url / не принимало, т.е.
http://site.ru/ or http://www.site.ru/ -верно

site.ru or www.site.ru or http://site.ru or http://www.site.ru - неверно

  Ответить  
 
 автор: ladan   (03.02.2012 в 18:21)   письмо автору
 
   для: TetRiska   (03.02.2012 в 17:48)
 

так?


<?
if(!preg_match("/^http:\/\/([a-z0-9-]{3,}\.[a-z]{2}\/|www\.[a-z0-9-]{3,}\.[a-z]{2}\/)$/i",$_GET['mat'])) echo "fail";

?>

  Ответить  
 
 автор: TetRiska   (03.02.2012 в 18:27)   письмо автору
 
   для: ladan   (03.02.2012 в 18:21)
 

а зачем www включили в регулярку? www неважен, но допустим....главное http:// - вначале и / - в конце строки

  Ответить  
 
 автор: ladan   (03.02.2012 в 18:32)   письмо автору
 
   для: TetRiska   (03.02.2012 в 18:27)
 

тогда так

if(!preg_match("/^http:\/\/[a-z0-9.-]{3,}\.[a-z]{2}\/$/i",$_GET['mat']))


это если вам важно .
главное http:// - вначале и / - в конце строки


могут такой адрес прописать http://.sait.ru/ с точной перед названием и регулярка пропустит

  Ответить  
 
 автор: TetRiska   (03.02.2012 в 18:38)   письмо автору
 
   для: ladan   (03.02.2012 в 18:32)
 

ммм, а как чтобы не могли в начале поставить, т.е. после http://
но должно пропускать http://d.site.ru/, т.е. поддомены

  Ответить  
 
 автор: ladan   (03.02.2012 в 18:47)   письмо автору
 
   для: TetRiska   (03.02.2012 в 18:38)
 

так

if(!preg_match("/^http:\/\/[a-z][a-z0-9.-]{3,}\.[a-z]{2}\/$/i",$_GET['mat']))


:)

  Ответить  
 
 автор: ladan   (03.02.2012 в 18:49)   письмо автору
 
   для: ladan   (03.02.2012 в 18:47)
 

а лучше чтоб в поддомен еще и цифры можно было...

if(!preg_match("/^http:\/\/[a-z0-9][a-z0-9.-]{3,}\.[a-z]{2}\/$/i",$_GET['mat'])) 

  Ответить  
 
 автор: TetRiska   (03.02.2012 в 19:21)   письмо автору
 
   для: ladan   (03.02.2012 в 18:49)
 

[a-z0-9.-]

а не?
[a-z0-9\.-]


и еще .org не пропустит, я замнил
[a-z]{2}

на
[a-z]{3}


немного не пойму принципа этой части {3,}

  Ответить  
 
 автор: ladan   (03.02.2012 в 19:39)   письмо автору
 
   для: TetRiska   (03.02.2012 в 19:21)
 

Тестил в разных вариантах, без разницы как использовать
[a-z0-9.-] и [a-z0-9\.-]


{3,}


Минимум 3 и до бесконечности

  Ответить  
 
 автор: ladan   (03.02.2012 в 20:01)   письмо автору
 
   для: ladan   (03.02.2012 в 19:39)
 

и еще .org не пропустит, я замнил


лучше так {2,3}

  Ответить  
 
 автор: TetRiska   (03.02.2012 в 20:05)   письмо автору
 
   для: ladan   (03.02.2012 в 19:39)
 

пропускает, а не должно
http://site..........org/
http://site..org/
http://site.tt..org/
http://site..tt.org/

http://site----.org/
http://site-.org/
http://site-tt-.org/
http://site--tt.org/

  Ответить  
 
 автор: ladan   (03.02.2012 в 20:47)   письмо автору
 
   для: TetRiska   (03.02.2012 в 20:05)
 

Я вас понял, подумал немного, сделал так



for($i = 0;$i < strlen($_GET['mat']); $i++)
{
$arr[] = $_GET['mat']{$i};
}
foreach($arr as $value)
{
if($value == ".") {$mas[] = $value;}
}



if(!preg_match("/^http:\/\/[a-z0-9][a-z0-9.-]{3,}\.[a-z]{2,3}\/$/i",$_GET['mat']) or strlen(implode("",$mas)) >= 3) echo "fail";



если будут найдено больше либо равно 3 точки, то фейл

С черточками тоже самое нужно сделать :)

Наверно извращение я написал, но работает с точками

  Ответить  
 
 автор: ladan   (03.02.2012 в 20:52)   письмо автору
 
   для: ladan   (03.02.2012 в 20:47)
 

.

  Ответить  
 
 автор: Sfinks   (04.02.2012 в 01:47)   письмо автору
 
   для: ladan   (03.02.2012 в 19:39)
 

> Тестил в разных вариантах, без разницы как использовать
. -обозначает любой символ. Т.е. [a-z0-9.-]{3,} пропускает абсолютно любую строку. Хоть !"/|\-=-/|\"!
и дефис, когда он в квадратных скобках, тоже нужно экранировать.

  Ответить  
 
 автор: Sfinks   (04.02.2012 в 01:43)   письмо автору
 
   для: TetRiska   (03.02.2012 в 17:48)
 

По-моему так должно быть:
<? 
if(!preg_match("#^http://(www\.)?([a-z0-9\-_]\.)+[a-z]{2,5}/$#i",$_GET['mat'])) echo "fail";

Это в простейшем варианте. По хорошему сейчас нужно еще кирилические ссылки разрешить и зоны обозначить не [a-z]{2,5}, а перечислить конкретно какие допустимы (ru|com|net|org|ua) ну и т.д.

  Ответить  
 
 автор: ladan   (04.02.2012 в 11:06)   письмо автору
 
   для: Sfinks   (04.02.2012 в 01:43)
 

мне кажется это плохая проверка на url :) тут же надо запрещать, если больше двух точек будет... а так думаю да, лучше перечислить
(ru|com|net|org|ua) 



<?

error_reporting
(0);
for(
$i 0;$i strlen($_GET['url']); $i++) 

$arr[] = $_GET['url']{$i}; 

foreach(
$arr as $value

if(
$value == ".") {$point[] = $value;} 


if(!
preg_match("/^http:\/\/[a-z0-9][a-z0-9\.\-]{2,}\.(ru|com|net|org|ua)\/$/i",$_GET['url']) or preg_match("/\.-|-\.|--|\.{2}/",$_GET['url'])  or strlen(implode("",$point)) >= 3) echo "fail";

?>

  Ответить  
 
 автор: Sfinks   (04.02.2012 в 14:24)   письмо автору
 
   для: ladan   (04.02.2012 в 11:06)
 

> тут же надо запрещать, если больше двух точек будет...
Каких двух точек? Типа http://ru.domen..com/ ?
А вы попробуйте пропихните ему (моему РВ) такую лажу.

А если речь идет об уровне поддомена, если например можно http://d.domain.com/ и нельзя http://ru.vasya.domain.site.com/ , то нужно просто + заменить на конкретное число:
#^http://(www\.)?([a-z0-9\-_]+\.){2,3}[a-z]{2,5}/$#i

P.S. Строго говоря, это не мое РВ, а общепринятая практика. Взято обшее выражение на проверку УРЛ, чтоб не изобретать велосипед, и УПРОЩЕНО под конкретную задачу. А вы изобретаете велосипед. И, извините, не спортивный велосипед, а советскую детскую машинку с педалями, если вы такие застали, в которую взрослый не поместится, а ребенку тяжело педали крутить.
P.P.S. Сори, в первой попытке потерял один плюсик. В 2 часа ночи писал все-таки =) Теперь правильно.

  Ответить  
 
 автор: ladan   (04.02.2012 в 16:03)   письмо автору
 
   для: Sfinks   (04.02.2012 в 14:24)
 

мне мой велосипед нравится :)
Просто автор попросил как нужно ему было, я так и сделал :)

  Ответить  
 
 автор: Sfinks   (04.02.2012 в 17:24)   письмо автору
 
   для: ladan   (04.02.2012 в 16:03)
 

> мне мой велосипед нравится :)
Допустим. Только ездит медленно и кругами. Думаю всем это очевидно, но попробую убедить в этом и вас.

Вы же не будете спорить с тем что программа должна работать как можно быстрее и есть как можно меньше памяти?
Давайте разберем ваш код по частям? что он проверяет? 3 вещи:
-соответствие шаблону, который, как вы считаете, описывает формат url;
-чтоб не было сочетаний .- -. -- и ..
-чтоб имя домена состояло не более чем из 3-ех частей. Т.е. либо domain.ru либо www.domain.ru либо sub.domain.ru. Так? Т.е. www.sub.domain.ru уже не пройдет, хотя как правило работает на равне с sub.domain.ru. И www.domain.ru.com тоже не пройдет, хотя регистрация домена в зоне .ru.com стоит 1700 рублей. Допустим, что так и надо. Но как вы это проверяете? Считаете количество точек? Допустим. Но как считаете??? Тут я вообще не могу поверить в то что вижу! Вы делаете В ЦИКЛЕ (!) из строки массив символов, только для того, чтобы В НОВОМ ЦИКЛЕ сделать массив точек и только после этого посчитать количество получившихся элементов??? А что считаете не в цикле? Написали бы так:
<?
$i 
0;
foreach(
$point as $value)  
{  
if(
$value == ".") {$i $i 1;}  
}
Это все одной функцией делается: substr_count($_GET['url']),".");
Но если вам в будущем понадобится разбить строку в массив, это тоже одной функцией делается: str_split($_GET['url']))
Но даже если вам когда-нибудь понадобится перебрать строку в цикле.... Нет не так. Никогда не задавайте границы цикла функциями! Сначала вычислите значение и запишите в переменную, а потом эту переменную передайте в цикл.
<?
$k 
strlen($_GET['url']);
for(
$i 0;$i $k$i++) { ... }
иначе ваша функция strlen($_GET['url']) будет выполняться каждый круг цикла.

Вернемся ко второму пункту ваших проверок... А чем вас не устраивают домены с -- или -. ?
Вот я создал пару поддоменов: http://d---b.d1m0k.ru/ и http://d-.d1m0k.ru
Они пока не доступны, надо дождаться пока DNS обновятся, но в целом это вполне реально. Можете завтра проверить эти адреса, они будут доступны.
На счет .- тут я согласен - упустил из вида. Но опять же это исправляется несколькими символами:
#^http://(www\.)?([a-z0-9][a-z0-9\-]*\.){2,3}[a-z]{2,5}/$#i

Я конечно понимаю, что нормальные герои всегда идут в обход, но прошу вас, не нужно =) Не привыкайте к этому.

  Ответить  
 
 автор: ladan   (04.02.2012 в 20:03)   письмо автору
 
   для: Sfinks   (04.02.2012 в 17:24)
 

www.sub.domain.ru

исправим на
strlen(implode("",$point)) >= 4)


С вами спорить не буду и сильно не пинайте меня, я php изучаю от силы 3 месяца :)

Спасибо за замечания =)

  Ответить  
 
 автор: Sfinks   (04.02.2012 в 20:16)   письмо автору
 
   для: ladan   (04.02.2012 в 20:03)
 

> сильно не пинайте меня, я php изучаю от силы 3 месяца
И не думал! Сори, если сложилось такое впечатление. Просто настоял на том чтоб вы прислушались =)

  Ответить  
 
 автор: TetRiska   (06.02.2012 в 12:39)   письмо автору
 
   для: Sfinks   (04.02.2012 в 20:16)
 

а как использовать в javascript-e?
var filter = #^http://(www\.)?([a-z0-9][a-z0-9\-]*\.){2,3}[a-z]{2,5}/$#i;
if(!filter.test($('input[name=link]').val())){
//fail
}

ругается на строку filter, я пробовал экранировать слеши, но регулярка не верно проверяет тогда, как исправить?
var filter = /#^http:\/\/(www\.)?([a-z0-9][a-z0-9\-]*\.){2,3}[a-z]{2,5}\/$#/i;

  Ответить  
 
 автор: TetRiska   (06.02.2012 в 12:46)   письмо автору
 
   для: TetRiska   (06.02.2012 в 12:39)
 

или так верно?
var filter = /^http:\/\/(www\.)?([a-z0-9][a-z0-9\-]*\.){2,3}[a-z]{2,5}\/$/i;


брал за пример
http://www.d.k-.d1m0k.ru/


1. www - не влияет на количество субдоменов, отлично
2 .макс. кол. субдоменов 3, мин. - 2....но тогда не пропустит
http://d1m0k.ru/
....тогда лучше {1,3}
3. кол. тире может быть сколько угодно, с ними, как я видел на примере, сайты создаются
4. с точками иначе, они не могут идти подряд, хорошо, т.. такие сайты не создаются

вроде бы и все, спасибо за помощь

  Ответить  
 
 автор: Sfinks   (06.02.2012 в 21:27)   письмо автору
 
   для: TetRiska   (06.02.2012 в 12:39)
 

Это лучше спросите в этом форуме. Я в JS не силен, а другие уже может не полезут в эту тему. Слишком она большая.

  Ответить  
 
 автор: TetRiska   (07.02.2012 в 16:12)   письмо автору
 
   для: Sfinks   (06.02.2012 в 21:27)
 

так работает :)
var filter = /^http:\/\/(www\.)?([a-z0-9][a-z0-9\-]*\.){2,3}[a-z]{2,5}\/$/i;

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования