RegExp для проверки URL (вечная тема)

Dreammaker

***=Ф=***
RegExp для проверки URL (вечная тема)

Нужен ReXexp для проверки URL на корректности введённого URL. Уже устал.... Если пишу свой, то через пару часов оказывается, что он что-то не учитывает... Просмотрел ен-мануал с комментариями, один приглянулся.... Но опять же пришлось дорабатывать, чтобы через несколько часов понять, что и этот не удовлетворяет.
Требования - http(s) ftp может быть, а может не быть в линке, если есть, то не важно присутствует www, или нет, если же http(s) ftp отсуствует, то www должно присутствовать обязательно.

Охватывать желательно все урлы начиная www.ya.ru (не сочтите за рекламу :) тут спонсор www.google.com как я понимаю:)), заканчивая http://www.nekiysite.nekiyserver.com.ru?n=modul&m=31545#qwert

понимаю, что универсального найти всё равно не удасться, но может....
 

Profic

just Profic (PHP5 BetaTeam)
Где-то так:
~(?:(?:ftp|https?)?://|www\.)[a-z_.]+?[a-z_]{2,6}:)?/[a-z0-9\-?\[\]=&;#]+)?~i
В последний символьный класс символы добавить по вкусу :)
 

sage

Новичок
через пару часов оказывается, что он что-то не учитывает...
универсального найти всё равно не удасться
мой тебе совет - не парься. самый верный способ проверки url - послать запрос на сервер и посмотреть, что в ответе.
 

Dreammaker

***=Ф=***
2 Profic. регексп любит отечественного производителя :)
www.ya.ru съел, а вот www.google.com ему не понравился :)
Также не захотел и другие более навороченные урлы :(

2 saqe. Проблемка в том, что мне потом этот регексп нужно использовать также и для автозамены урлов в тексте. А проверять не является ли каждое слово урлом путём отсылки запроса к потенциальным серверам. Это будет конечно черезчур... + cервер может быть в дауне.
 

Profic

just Profic (PHP5 BetaTeam)
Dreammaker
www.ya.ru съел, а вот www.google.com ему не понравился
Значит не так приготовили:
E:\work\web\SDN\recipe-nddocs\cpp\rtf2html>php
PHP:
<?php
var_dump(preg_match('~(?:(?:ftp|https?)?://|www\.)[a-z_.]+?[a-z_]{2,6}(:?/[a-z0-9\-?\[\]=&;#]+)?~i', 'www.google.com'));
?>
^Z
int(1)

E:\work\web\SDN\recipe-nddocs\cpp\rtf2html>php
PHP:
<?php
var_dump(preg_match('~(?:(?:ftp|https?)?://|www\.)[a-z_.]+?[a-z_]{2,6}(:?/[a-z0-9\-?\[\]=&;#]+)?~i', 'http://www.nekiysite.nekiyserver.com.ru/?n=modul&m=31545#qwert'));
?>
^Z
int(1)

E:\work\web\SDN\recipe-nddocs\cpp\rtf2html>
 

Dreammaker

***=Ф=***
PHP:
<?echo var_dump(preg_match('~(?:(?:ftp|https?)?://|www\.)[a-z_.]+?[a-z_]{2,6}(:?/[a-z0-9\-?\[\]=&;#]+)?~i', 'www.google.com78787878'));?>
int(1)

у классиков (Mastering Regular Expressions ) та же проблема

:)
PHP:
<?echo var_dump(preg_match("~((ftp|https?)://[-\w]+(\.\w[-\w]*)+|(?i: [a-z0-9] (?:[-a-z0-9]*[a-z0-9])?\.)+(?-i:com\b|edu\b|biz\b|gov\b|in(?:t|fo)\b|mil\b|net\b|org\b|museum\b\[a-z][a-z]\b))(:\d+)?(/[^.!,?;\"\'<>()\[\]{}\s\x7F-\xFF]*(?:[.!,?]+[^.!,?;\"\'<>()\[\]{}\s\x7F-\xFF]+)*)?~", 'http://www.google.com78787878'));?>
код немного доделан (например, слышами кавычки экранировал + музеум добавил) и плюс проверки на www - нет, но факт остаётся фактом int(1).
 

Profic

just Profic (PHP5 BetaTeam)
Для начала - это в принципе валидный урл.
Дальше, вы все равно их не так готовите:
E:\work\web\SDN\recipe-nddocs\cpp\rtf2html>php
PHP:
<?php
echo preg_replace('~(?:(?:ftp|https?)?://|www\.)(?:[a-z_]+\.)*[a-z_]{2,6}(:?/[a-z0-9\-?\[\]=&;#]+)?~i', '|$0|', 'www.goo
gle.com12345');
?>
^Z
|www.google.com|12345
E:\work\web\SDN\recipe-nddocs\cpp\rtf2html>
Такой рег можно усложнять до безобразия, но он все равно не будет 100% отсеивать неверные урлы.
 

Dreammaker

***=Ф=***
PHP:
<?php 
function url_check($buf)
{
      $buf=trim($buf);
      preg_match("~(?:(?:ftp|https?)?://|www\.)(?:[a-z0-9\-]+\.)*[a-z]{2,6}(:?/[a-z0-9\-?\[\]=&;#]+)?~i",$buf,$mat);
      return (isset($mat))?($mat[0]==$buf)?$mat[0]:0:0;

      //если существует массив $mat и равны входные данные и то, что получили от рега, то значит урл валидный и возвращаем его, если нет то вовращаем 0.
}
$buf="www.nekiysite.nekiyserver.com.ru/n=modul&m=31545#qwert";


echo url_check($buf);
//www.nekiysite.nekiyserver.com.ru/n=modul&m=31545#qwert


$buf="www.nekiysite.nekiys'erver.com.ru/n=modul&m=31545#qwert";

echo url_check($buf);
//0
?>


В такой кастрюле готовить нормально?
Оно работает в терпимых границах:) Спасибо!

./******отредактировал. убрал символы подчёркивания по совету Фаната. Насчёт ниже лежащего поста - пока думаю**********/

p.s. Если терпимо, то эту тему можно заносить в избранное или в FAQ. Думаю, что это многим будет полезно и интересно (хотя могу ошибаться), да и на грабли на чужие не будут наступать.
 

sage

Новичок
Т.к. :// относится к названию протокола, то эта часть выражения слегка неточная. Вот более правильная: (?:(?:ftp|https?)://)?
 

Фанат

oncle terrible
Команда форума
зачем в имени домена символ подчёркивания?
для подсветки урлов функция не годится - русский, к примеру, не поймёт в параметрах - а удобно.
для проверки - может быть...
 

MD

Guest
Dreammaker
нафиг оно не нужно в избранном, ибо проверка урл на валидность не имеет практической пользы.
 

Лисю

Guest
PHP:
//--------------------------------------------------------------------
//	Проверяет строку на соответствие URL адресу
//	возвращает true в случае если ввод корректен
//	false в противном случае
//--------------------------------------------------------------------
function is_url($in){
	$w = "a-z0-9";
	$url_pattern = "#(
	(?:f|ht)tps?://(?:www.)?
	(?:[$w\\-.]+/?\\.[a-z]{2,4})/?
	(?:[$w\\-./\\#]+)?
	(?:\\?[$w\\-&=;\\#]+)?
	)#xi";
	
	$a =  preg_match($url_pattern,$in);
	return $a;
}
[Posted by 213.171.59.204. This is added while posting a message via http://webwarper.net to avoid misuse of WebWarper. Example of using WebWarper: http://webwarper.net/ww/~av/lycos.com ]
 

Dreammaker

***=Ф=***
MD Ну мне то понадобилось... :)
Ок. Не нужно в избранное - так не нужно... Спорить не буду. Главное, что она для меня полезной будет.

Во, не успеваю написать, как уже ответы поступают.
Там ещё не только убрать подчёркивание нужно, но и дефисы добавить в имя домена, который не ТЛД, и циферки в имя домена тоже... Сейчас сделаю...

Конечно, можно ещё поставить проверку на , чтобы первыми дефисы не шли, но мне и этого хватит

Насчёт функции выше, то она похожа. Единственно, что всё таки в моём случае нужно возвращать или нуль или имя урла, как это сделано в функции url_check().
 

MD

Guest
Alexandre
примеров не встречал.

толку мне от того, что http://www.sadfjhsdfkshdfksh__sdfjhsdfs.com валидный? :)
 
Сверху