Web

PHP валидация/регулярное выражение для URL

Я искал простой regex для URL, есть ли у кого-нибудь такой, который хорошо работает? Я не нашел такого в классах валидации zend framework и в других реализациях.

Ответ 1

Я использовал этот код в нескольких проектах, но я уверен, что это не исчерпывающий вариант:

$text = preg_replace(

  '#((https?|ftp)://(\S*?\.\S*?))([\s)\[\]{},;"\':<]|\.\s|$)#i',

  "'<a href=\"$1\" target=\"_blank\">$3</a>$4'",

  $text

);

Большая часть случайного «кода» в конце для решения таких ситуаций, как http://domain.com. в предложении (чтобы избежать совпадения с последующим периодом). Я уверен, что это можно убрать, но это работает.

 

Ответ 2

Используйте функцию filter_var() для проверки того, является ли строка URL или нет:

var_dump(filter_var('example.com', FILTER_VALIDATE_URL));

Использование регулярных выражений без необходимости плохая практика.

Будьте осторожны, это решение не является юникод-безопасным и XSS-безопасным. Если вам нужна сложная валидация, возможно, лучше поискать другое решение.


Ответ 3

На случай, если вы хотите узнать, существует ли URL на самом деле:

function url_exist($url){

    $c=curl_init();

    curl_setopt($c,CURLOPT_URL,$url);

    curl_setopt($c,CURLOPT_HEADER,1); // получение заголовка

    curl_setopt($c,CURLOPT_NOBODY,1);    curl_setopt($c,CURLOPT_RETURNTRANSFER,1); // получить ответ в виде строки из curl_exec(), вместо того чтобы передавать его эхом

    curl_setopt($c,CURLOPT_FRESH_CONNECT,1); // не использовать кэшированную версию урла

    if(!curl_exec($c)){

        //echo $url.' inexists';

        return false;

    }else{

        //echo $url.' exists';

        return true;

    }

    //$httpcode=curl_getinfo($c,CURLINFO_HTTP_CODE);

    //return ($httpcode<400);

}

 

Ответ 4

Регулярное выражение:

(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s'!()\[\]{};:'\".,<>?«»“”'']))

использование в preg_match():

preg_match("/(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s'!()\[\]{};:'\".,<>?«»“”'']))/", $url)

Вот расширенный шаблон регулярного выражения (с комментариями):

 (?xi)

\b

(                                                     # Захват 1: весь совпадающий URL

  (?:

    https?://                                     # http или https протокол

    |                                                 # или

    www\d{0,3}[.]                             # "www.", "www1.", "www2." … "www999."

    |                                                 # или

    [a-z0-9.\-]+[.][a-z]{2,4}/             # выглядит как доменное имя, за которым следует слэш  )

  (?:                                                # варианты:

    [^\s()<>]+                                  # не пробел и не-()<>

    |                                                 # или

    \(([^\s()<>]+|(\([^\s()<>]+\)))*\)  # сбалансированные родительские элементы, до 2 уровней

  )+

  (?:                                                # в конце:

    \(([^\s()<>]+|(\([^\s()<>]+\)))*\)  # сбалансированные родительские элементы, до 2 уровней

    |                                                 #   или

    [^\s'!()\[\]{};:'".,<>?«»“”'']           # не пробел или один из этих пунктуационных символов

  )

)

 

Ответ 5

Я не думаю, что в данном случае разумно использовать регулярные выражения. Невозможно сопоставить все возможности, и даже если вы это сделали, все равно есть вероятность, что URL-адрес просто не существует.

Вот очень простой способ проверить, действительно ли URL существует и доступен для чтения:

if (preg_match("#^https?://.+#", $link) and @fopen($link,"r")) echo "OK";

 

Ответ 6

function validateURL($URL) {

      $pattern_1 = "/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i";

      $pattern_2 = "/^(www)((\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i";       

      if(preg_match($pattern_1, $URL) || preg_match($pattern_2, $URL)){

        return true;

      } else{

        return false;

      }

}

 

Ответ 7

Вот наиболее полное решение вашей проблемы.

function link_validate_url($text) {

 $LINK_DOMAINS = 'aero|arpa|asia|biz|com|cat|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|mobi|local';

  $LINK_ICHARS_DOMAIN = (string) html_entity_decode(implode("", array( // @TODO completing letters ...

    "&#x00E6;", // æ

    "&#x00C6;", // Æ

    "&#x00C0;", // À

    "&#x00E0;", // à

    "&#x00C1;", // Á

    "&#x00E1;", // á

    "&#x00C2;", // Â

    "&#x00E2;", // â

    "&#x00E5;", // å

    "&#x00C5;", // Å

    "&#x00E4;", // ä

    "&#x00C4;", // Ä

    "&#x00C7;", // Ç

    "&#x00E7;", // ç

    "&#x00D0;", // Ð

    "&#x00F0;", // ð

    "&#x00C8;", // È

    "&#x00E8;", // è

    "&#x00C9;", // É

    "&#x00E9;", // é

    "&#x00CA;", // Ê

    "&#x00EA;", // ê

    "&#x00CB;", // Ë

    "&#x00EB;", // ë

    "&#x00CE;", // Î

    "&#x00EE;", // î

    "&#x00CF;", // Ï

    "&#x00EF;", // ï

    "&#x00F8;", // ø

    "&#x00D8;", // Ø

    "&#x00F6;", // ö

    "&#x00D6;", // Ö

    "&#x00D4;", // Ô

    "&#x00F4;", // ô

    "&#x00D5;", // Õ

    "&#x00F5;", // õ

    "&#x0152;", // Œ

    "&#x0153;", // œ

    "&#x00FC;", // ü

    "&#x00DC;", // Ü

    "&#x00D9;", // Ù

    "&#x00F9;", // ù

    "&#x00DB;", // Û

    "&#x00FB;", // û

    "&#x0178;", // Ÿ

    "&#x00FF;", // ÿ 

    "&#x00D1;", // Ñ

    "&#x00F1;", // ñ

    "&#x00FE;", // þ

    "&#x00DE;", // Þ

    "&#x00FD;", // ý

    "&#x00DD;", // Ý

    "&#x00BF;", // ¿

  )), ENT_QUOTES, 'UTF-8');

  $LINK_ICHARS = $LINK_ICHARS_DOMAIN . (string) html_entity_decode(implode("", array(

    "&#x00DF;", // ß

  )), ENT_QUOTES, 'UTF-8');

  $allowed_protocols = array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal');

  // Начало группы скобок с (?: означает, что она сгруппирована, но не захвачена

  $protocol = '((?:'. implode("|", $allowed_protocols) .'):\/\/)';

  $authentication = "(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=" . $LINK_ICHARS . "]|%[0-9a-f]{2})+(?::(?:[\w". $LINK_ICHARS ."\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})*)?)?@)";

  $domain = '(?:(?:[a-z0-9' . $LINK_ICHARS_DOMAIN . ']([a-z0-9'. $LINK_ICHARS_DOMAIN . '\-_\[\]])*)(\.(([a-z0-9' . $LINK_ICHARS_DOMAIN . '\-_\[\]])+\.)*('. $LINK_DOMAINS .'|[a-z]{2}))?)';

  $ipv4 = '(?:[0-9]{1,3}(\.[0-9]{1,3}){3})';

  $ipv6 = '(?:[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7})';

  $port = '(?::([0-9]{1,5}))';

  // Шаблон, специфичный для внешних ссылок.

  $external_pattern = '/^'. $protocol .'?'. $authentication .'?('. $domain .'|'. $ipv4 .'|'. $ipv6 .' |localhost)'. $port .'?';

  // Шаблон, специфичный для внутренних ссылок.

  $internal_pattern = "/^(?:[a-z0-9". $LINK_ICHARS ."_\-+\[\]]+)";

  $internal_pattern_file = "/^(?:[a-z0-9". $LINK_ICHARS ."_\-+\[\]\.]+)$/i";

  $directories = "(?:\/[a-z0-9". $LINK_ICHARS ."_\-\.~+%=&,$'#!():;*@\[\]]*)*";

  // Да, четыре обратных слеша == один обратный слеш.

  $query = "(?:\/?\?([?a-z0-9". $LINK_ICHARS ."+_|\-\.~\/\\\\%=&,$'():;*@\[\]{} ]*))";

  $anchor = "(?:#[a-z0-9". $LINK_ICHARS ."_\-\.~+%=&,$'():;*@\[\]\/\?]*)";

  // Оставшаяся часть пути для стандартного URL.

  $end = $directories .'?'. $query .'?'. $anchor .'?'.'$/i';

  $message_id = '[^@].*@'. $domain;

  $newsgroup_name = '(?:[0-9a-z+-]*\.)*[0-9a-z+-]*';

  $news_pattern = '/^news:('. $newsgroup_name .'|'. $message_id .')$/i';

  $user = '[a-zA-Z0-9'. $LINK_ICHARS .'_\-\.\+\^!#\$%&*+\/\=\?\'\|\{\}~\'\[\]]+';

  $email_pattern = '/^mailto:'. $user .'@'.'(?:'. $domain .'|'. $ipv4 .'|'. $ipv6 .'|localhost)'. $query .'?$/';

  if (strpos($text, '<front>') === 0) {

    return false;

  }

  if (in_array('mailto', $allowed_protocols) && preg_match($email_pattern, $text)) {

    return false;

  }

  if (in_array('news', $allowed_protocols) && preg_match($news_pattern, $text)) {

    return false;

  }

  if (preg_match($internal_pattern . $end, $text)) {

    return false;

  }

  if (preg_match($external_pattern . $end, $text)) {

    return false;

  }

  if (preg_match($internal_pattern_file, $text)) {

    return false;

  }

  return true;

}

Схожие статьи

Web

Почему move_uploaded_file выдает ошибку «Не удалось открыть поток: в доступе отказано»

Как создать грамотное оформление страницы 404 на собственном сайте
Web

Как создать грамотное оформление страницы 404 на собственном сайте

Web

Как правильно определить, является ли строка даты допустимой датой в определенном формате

Что за профессия веб-разработчик: обязанности и зарплата
Web

Что за профессия веб-разработчик: обязанности и зарплата