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

Как запретить прямой доступ к включаемому файлу php

Международные биржи фриланса: фриланс за рубежом — это просто!
Web

Международные биржи фриланса: фриланс за рубежом — это просто!

Web

Множественные выходы из функции

Web

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

×