用于URL的PHP​​验证/正则表达式

And*_*iem 118 php regex validation url

我一直在寻找一个简单的URL正则表达式,有没有人有一个方便的工作?我没有找到一个zend框架验证类,并看到了几个实现.

谢谢

Sta*_*lav 202

使用该filter_var()函数验证字符串是否为URL:

var_dump(filter_var('example.com', FILTER_VALIDATE_URL));
Run Code Online (Sandbox Code Playgroud)

在不需要时使用正则表达式是不好的做法.

编辑:小心,这个解决方案不是unicode安全的,不是XSS安全的.如果您需要复杂的验证,也许最好还是寻找其他地方.

  • 5.2.13(我认为5.3.2)中存在一个错误,它阻止带有破折号的网址使用此方法进行验证. (29认同)
  • filter_var将拒绝http://test-site.com,我有破折号的域名,他们是否有效.我不认为filter_var是验证网址的最佳方式.它将允许像`http:// www`这样的网址 (13认同)
  • 这种方法的另一个问题是它不是unicode安全的. (11认同)
  • >它会允许像'http:// www'这样的网址当像'http:// localhost'这样的网址时可以 (4认同)
  • FILTER_VALIDATE_URL有很多问题需要修复(https://bugs.php.net/search.php?cmd=display&search_for=FILTER_VALIDATE_URL).此外,[描述标志的文档](http://php.net/manual/en/filter.filters.validate.php)不反映[实际源代码](https://github.com/php/ php-src/blob/master/ext/filter/logical_filters.c#L517)其中对某些标志的引用已被完全删除.更多信息:http://news.php.net/php.internals/99018 (2认同)

Owe*_*wen 75

我在一些项目中使用过这个,我不相信我遇到了问题,但我确信它并非详尽无遗:

$text = preg_replace(
  '#((https?|ftp)://(\S*?\.\S*?))([\s)\[\]{},;"\':<]|\.\s|$)#i',
  "'<a href=\"$1\" target=\"_blank\">$3</a>$4'",
  $text
);
Run Code Online (Sandbox Code Playgroud)

最后的大多数随机垃圾是处理http://domain.com.句子中的情况(以避免匹配尾随时期).我确信它可以清理,但因为它有效.我或多或少只是将它从项目复制到项目.

  • 有些事情在我身上跳出来:使用交替来调用字符类(每个选项只匹配一个字符); 并且替换不应该需要外部双引号(仅因为正则表达式上的无意义/ e修饰符而需要它们). (7认同)
  • 这里有很棒的综合资源:http://mathiasbynens.be/demo/url-regex (7认同)

cat*_*ave 27

按照PHP手册- parse_url应该不会被用于验证URL.

不幸的是,似乎filter_var('example.com', FILTER_VALIDATE_URL)没有更好的表现.

双方parse_url()filter_var()会通过恶意的URL,例如http://...

因此在这种情况下 - 正则表达式更好的方法.

  • 这个论点没有遵循.如果FILTER_VALIDATE_URL比您想要的更宽松一些,请使用一些额外的检查来处理这些边缘情况.你自己尝试对网址进行正则表达式重新发明轮子只会让你进一步完成检查. (10认同)
  • 你为Tchalvak做了一个公平的话.像URL一样的正则表达式(根据其他响应)很难做到正确.正则表达并不总是答案.相反,正则表达式也不总是错误的答案.重要的一点是为工作选择正确的工具(正则表达式或其他),而不是具体的"反"或"专业"正则表达式.事后看来,你使用filter_var与其边缘情况的约束相结合的答案看起来更好的答案(特别是当正则表达式的答案开始达到大于100个字符左右时 - 使所述正则表达式的维护成为一场噩梦) (3认同)
  • 查看此页面上的所有击落正则表达式,了解为什么不编写自己的正则表达式. (2认同)

Rog*_*ger 12

万一你想知道网址是否真的存在:

function url_exist($url){//se passar a URL existe
    $c=curl_init();
    curl_setopt($c,CURLOPT_URL,$url);
    curl_setopt($c,CURLOPT_HEADER,1);//get the header
    curl_setopt($c,CURLOPT_NOBODY,1);//and *only* get the header
    curl_setopt($c,CURLOPT_RETURNTRANSFER,1);//get the response as a string from curl_exec(), rather than echoing it
    curl_setopt($c,CURLOPT_FRESH_CONNECT,1);//don't use a cached version of the url
    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);
}
Run Code Online (Sandbox Code Playgroud)

  • 直接访问用户输入的URL是否存在安全风险? (7认同)

abh*_*kar 10

按照John Gruber(Daring Fireball)的说法:

正则表达式:

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

在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)
Run Code Online (Sandbox Code Playgroud)

这是扩展的正则表达式模式(带注释):

(?xi)
\b
(                       # Capture 1: entire matched URL
  (?:
    https?://               # http or https protocol
    |                       #   or
    www\d{0,3}[.]           # "www.", "www1.", "www2." … "www999."
    |                           #   or
    [a-z0-9.\-]+[.][a-z]{2,4}/  # looks like domain name followed by a slash
  )
  (?:                       # One or more:
    [^\s()<>]+                  # Run of non-space, non-()<>
    |                           #   or
    \(([^\s()<>]+|(\([^\s()<>]+\)))*\)  # balanced parens, up to 2 levels
  )+
  (?:                       # End with:
    \(([^\s()<>]+|(\([^\s()<>]+\)))*\)  # balanced parens, up to 2 levels
    |                               #   or
    [^\s`!()\[\]{};:'".,<>?«»“”‘’]        # not a space or one of these punct chars
  )
)
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请查看:http: //daringfireball.net/2010/07/improved_regex_for_matching_urls


小智 9

在这种情况下,我不认为使用正则表达式是明智的做法.不可能匹配所有可能性,即使你这样做,仍然有可能网址根本不存在.

这是一个非常简单的方法来测试url是否实际存在且可读:

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

(如果没有,preg_match那么这也会验证服务器上的所有文件名)


小智 7

    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;
      }
    }
Run Code Online (Sandbox Code Playgroud)


Pet*_*ley 6

我已经用这个很成功 - 我不记得从哪里得到它

$pattern = "/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i";
Run Code Online (Sandbox Code Playgroud)


Fra*_*kie 5

编辑:
正如发生率指出的那样,此代码已随 PHP 5.3.0 (2009-06-30) 的发布而被弃用,应相应地使用。


只是我的两美分,但我已经开发了这个功能并且已经成功使用了一段时间。它有很好的文档记录和分离,因此您可以轻松更改它。

// Checks if string is a URL
// @param string $url
// @return bool
function isURL($url = NULL) {
    if($url==NULL) return false;

    $protocol = '(http://|https://)';
    $allowed = '([a-z0-9]([-a-z0-9]*[a-z0-9]+)?)';

    $regex = "^". $protocol . // must include the protocol
             '(' . $allowed . '{1,63}\.)+'. // 1 or several sub domains with a max of 63 chars
             '[a-z]' . '{2,6}'; // followed by a TLD
    if(eregi($regex, $url)==true) return true;
    else return false;
}
Run Code Online (Sandbox Code Playgroud)

  • @YzmirRamirez(这么多年之后......)如果你在写评论时有任何疑问,现在肯定没有,这些天使用顶级域名,例如 .photography (2认同)

Geo*_*nas 5

并且有你的答案=)试着打破它,你不能!

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');

  // Starting a parenthesis group with (?: means that it is grouped, but is not captured
  $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}))';

  // Pattern specific to external links.
  $external_pattern = '/^'. $protocol .'?'. $authentication .'?('. $domain .'|'. $ipv4 .'|'. $ipv6 .' |localhost)'. $port .'?';

  // Pattern specific to internal links.
  $internal_pattern = "/^(?:[a-z0-9". $LINK_ICHARS ."_\-+\[\]]+)";
  $internal_pattern_file = "/^(?:[a-z0-9". $LINK_ICHARS ."_\-+\[\]\.]+)$/i";

  $directories = "(?:\/[a-z0-9". $LINK_ICHARS ."_\-\.~+%=&,$'#!():;*@\[\]]*)*";
  // Yes, four backslashes == a single backslash.
  $query = "(?:\/?\?([?a-z0-9". $LINK_ICHARS ."+_|\-\.~\/\\\\%=&,$'():;*@\[\]{} ]*))";
  $anchor = "(?:#[a-z0-9". $LINK_ICHARS ."_\-\.~+%=&,$'():;*@\[\]\/\?]*)";

  // The rest of the path for a standard 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;
}
Run Code Online (Sandbox Code Playgroud)


Fre*_*lli 5

对我有用的最佳 URL 正则表达式:

function valid_URL($url){
    return preg_match('%^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@|\d{1,3}(?:\.\d{1,3}){3}|(?:(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)(?:\.(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)*(?:\.[a-z\x{00a1}-\x{ffff}]{2,6}))(?::\d+)?(?:[^\s]*)?$%iu', $url);
}
Run Code Online (Sandbox Code Playgroud)

例子:

valid_URL('https://twitter.com'); // true
valid_URL('http://twitter.com');  // true
valid_URL('http://twitter.co');   // true
valid_URL('http://t.co');         // true
valid_URL('http://twitter.c');    // false
valid_URL('htt://twitter.com');   // false

valid_URL('http://example.com/?a=1&b=2&c=3'); // true
valid_URL('http://127.0.0.1');    // true
valid_URL('');                    // false
valid_URL(1);                     // false
Run Code Online (Sandbox Code Playgroud)

来源:http : //urlregex.com/