URL için PHP doğrulaması / regex


125

URL'ler için basit bir normal ifade arıyordum, iyi çalışan kullanışlı bir tane var mı? Zend çerçeve doğrulama sınıflarıyla bir tane bulamadım ve birkaç uygulama gördüm.


1
Bu oldukça iyi bir kaynak. Çok sayıda farklı model ve testin bir listesini verir: mathiasbynens.be/demo/url-regex
omar j

Yanıtlar:


79

Bunu birkaç projede kullandım, sorunlarla karşılaştığıma inanmıyorum, ancak kapsamlı olmadığına eminim:

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

http://domain.com.Sondaki rastgele önemsiz şeylerin çoğu, cümle gibi durumlarla uğraşmaktır (sondaki dönemin eşleşmesini önlemek için). Eminim temizlenebilirdi ama işe yaradığından beri. Az ya da çok onu projeden projeye kopyaladım.


7
Aklıma gelen bazı şeyler: karakter sınıflarının istendiği yerde değişim kullanımı (her alternatif tam olarak bir karakterle eşleşir); ve değiştirme, dış çift tırnaklara ihtiyaç duymamalıydı (bunlar yalnızca normal ifadedeki anlamsız / e değiştiricisi nedeniyle gerekliydi).
Alan Moore

1
@John Scipione: google.comyalnızca geçerli bir göreli URL yoludur, ancak geçerli bir mutlak URL değildir. Ve bence onun aradığı şey bu.
Gumbo

Bu, bu durumda işi değil - bu sondaki "içerir: 3 cantari noi içinde albumul <a href=" audio.resursecrestine.ro/cantece/index-autori/andrei-rosu/...>
Softy

1
@Softy gibi http://example.com/somedir/...bir şey , ...meşru bir dosya adı olan adlandırılmış dosyayı isteyen, tamamen meşru bir URL'dir .
Stephen P

Deseninizi kullanarak url'yi doğrulamak için Zend \ Doğrulayıcı \ Regex kullanıyorum, ancak yine http://www.examplede geçerli olduğunu tespit ediyor
Joko Wandiro

207

filter_var()Bir dizenin URL olup olmadığını doğrulamak için işlevi kullanın :

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

Gerekli olmadığında normal ifadeleri kullanmak kötü bir uygulamadır.

DÜZENLEME : Dikkatli olun, bu çözüm unicode güvenli değildir ve XSS güvenli değildir. Karmaşık bir doğrulamaya ihtiyacınız varsa, belki başka bir yere bakmak daha iyidir.


29
5.2.13'te (ve bence 5.3.2), içinde tire bulunan url'lerin bu yöntemi kullanarak doğrulamasını engelleyen bir hata var.
vamin

14
filter_var test-site.com'u reddedecek , geçerli olsun ya da olmasın kısa çizgiler içeren alan adlarım var. Filter_var'ın bir url'yi doğrulamanın en iyi yolu olduğunu düşünmüyorum. Şöyle bir url'ye izin verecekhttp://www
Cesar

4
> ' Www ' gibi bir url'ye izin verecek URL'nin ' localhost ' gibi olması sorun değil
Stanislav

12
Bu yöntemle ilgili diğer sorun, unicode güvenli olmamasıdır.
Benji XVI

3
FILTER_VALIDATE_URL'de düzeltilmesi gereken birçok sorun var. Ayrıca, bayrakları açıklayan dokümanlar , bazı bayraklara yapılan referansların tamamen kaldırıldığı gerçek kaynak kodunu yansıtmaz . Daha fazla bilgi burada: news.php.net/php.internals/99018
S. Imp

29

PHP kılavuzu gereğince - parse_url gerektiğini değil bir URL doğrulamak için kullanılabilir.

Ne yazık ki, filter_var('example.com', FILTER_VALIDATE_URL)daha iyi bir performans göstermiyor gibi görünüyor .

Her ikisi de parse_url()ve filter_var()gibi hatalı biçimlendirilmiş URL'leri geçirecekhttp://...

Dolayısıyla bu durumda - regex olduğunu daha iyi bir yöntem.


10
Bu argüman takip etmiyor. FILTER_VALIDATE_URL istediğinizden biraz daha fazla izin veriyorsa, bu uç durumlarla başa çıkmak için bazı ek kontroller yapın. Tekerleği kendi url'lere karşı bir regex denemenizle yeniden icat etmek, sizi tam bir kontrolden daha ileriye götürür.
Kzqai

2
Kendi yazınızı neden yazmamanız gerektiğine dair örnekler için bu sayfadaki tüm azaltılmış normal ifadelere bakın.
Kzqai

3
Adil bir noktaya değindin Tchalvak. URL'ler gibi bir şey için normal ifadelerin (diğer yanıtlara göre) doğru olması çok zor olabilir. Regex her zaman cevap değildir. Tersine regex de her zaman yanlış cevap değildir. Önemli olan, iş için doğru aracı (normal ifade veya başka türlü) seçmek ve özellikle "anti" veya "pro" normal ifade olmamaktır. Geriye dönüp baktığımızda, filter_var'ı uç durumlardaki kısıtlamalarla birlikte kullanma cevabınız daha iyi bir cevap gibi görünüyor (özellikle normal ifade cevapları 100'den fazla karaktere ulaşmaya başladığında - söz konusu normal ifadenin bakımını bir kabusa
çevirmek

12

URL'nin gerçekten var olup olmadığını bilmek istemeniz durumunda:

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

1
Yine de $urlurl'nin gerçek olduğunu doğrulamadan önce bir çeşit doğrulama yapardım çünkü yukarıdaki işlem pahalıdır - dosya boyutuna bağlı olarak belki 200 milisaniye kadar. Bazı durumlarda, url'nin konumunda henüz kullanılabilir bir kaynak olmayabilir (örneğin, henüz yüklenmemiş bir görüntünün URL'sinin oluşturulması). Ek olarak, önbelleğe alınmış bir sürümü kullanmıyorsunuz, bu nedenle bu file_exists(), bir dosyadaki bir durumu önbelleğe alacak ve neredeyse anında geri dönecek. Sağladığınız çözüm yine de faydalı. Neden sadece kullanmıyorsun fopen($url, 'r')?
Yzmir Ramirez

Teşekkürler, tam aradığım şey. Ancak kullanmaya çalışırken bir hata yaptım. İşlev "url_exist" değil, "url_exists" oops ;-)
PJ Brunet

9
Kullanıcı tarafından girilen URL'ye doğrudan erişimde herhangi bir güvenlik riski var mı?
siliconpi

bir 404 bulunup bulunmadığına bir kontrol eklemek istersiniz: <code> $ httpCode = curl_getinfo ($ c, CURLINFO_HTTP_CODE); // echo $ url. ''. $ httpCode. '<br>'; eğer ($ httpCode == 404) {echo $ url. ' 404' ; } </code>
Camaleo

Hiç güvenli değil .. herhangi bir giriş URL'sine aktif olarak erişilebilir.
dmmd

11

Gereğince John Gruber (Cesur Fireball):

regex:

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

preg_match () kullanarak:

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

Genişletilmiş normal ifade kalıbı (yorumlarla birlikte):

(?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
  )
)

Daha fazla ayrıntı için lütfen şu adrese bakın: http://daringfireball.net/2010/07/improved_regex_for_matching_urls


9

Bu durumda normal ifadeler kullanmanın akıllıca bir şey olduğunu düşünmüyorum. Tüm olasılıkları eşleştirmek imkansızdır ve yapmış olsanız bile, url'nin var olmaması ihtimali hala vardır.

URL'nin gerçekten var olup olmadığını ve okunabilir olup olmadığını test etmenin çok basit bir yolu:

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

(eğer yoksa, preg_matchbu aynı zamanda sunucunuzdaki tüm dosya adlarını da doğrular)


7

Bunu başarılı bir şekilde kullandım - nereden aldığımı hatırlamıyorum

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

^ (http: // | https: //)??? (([a-z0-9] ([-a-z0-9] * [a-z0-9] +)) {1,63} \ .) + [az] {2,6} (çok açgözlü olabilir, henüz emin değilim, ancak protokol ve lider www konusunda daha esnektir)
andrewbadera

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;
      }
    }

'Www.w3schools.com/home/3/?a=l'
user3396065

5

Ve cevabınız var =) Kırmaya çalışın, yapamazsınız !!!

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;
}

Çok daha fazla üst düzey alan var .
Jeff Puckett

4

Düzenleme:
As insidans işaret Bu kod PHP 5.3.0 (2009-06-30) sürümü ile KALDIRILDI edilmiş ve buna göre kullanılmalıdır.


Sadece iki sentim ama bu işlevi geliştirdim ve bir süredir başarıyla kullanıyorum. İyi bir şekilde belgelenmiştir ve ayrılmıştır, böylece kolayca değiştirebilirsiniz.

// 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;
}

1
Eregi, PHP 6.0.0'da kaldırılacaktır. Ve "öäåø" içeren alanlar işlevinizle doğrulanmayacaktır. Muhtemelen önce URL'yi punycode'a dönüştürmelisiniz?

@ tesadüf kesinlikle katılıyorum. Bunu Mart'ta yazdım ve PHP 5.3 yalnızca Haziran sonunda eregi'yi KULLANIMDAN KALDIRILDI olarak ayarlayarak çıktı. Teşekkür ederim. Düzenlenecek ve güncellenecek.
Frankie

Yanılıyorsam düzeltin, ancak yine de TLD'lerin minimum 2 karakter ve maksimum 6 karakter olacağını varsayabilir miyiz?
Yzmir Ramirez

2
@YzmirRamirez (Tüm bu yıllar sonra ...) Yorumunuzu yazarken herhangi bir şüpheniz varsa, bugünlerde .photography gibi TLD'lerle
Nick Rice

@NickRice haklısın ... 5 yıl içinde web ne kadar değişiyor. Şimdi birisi TLD'yi yapana kadar bekleyemem .supercalifragilisticexpialidocious
Yzmir Ramirez

4
function is_valid_url ($url="") {

        if ($url=="") {
            $url=$this->url;
        }

        $url = @parse_url($url);

        if ( ! $url) {


            return false;
        }

        $url = array_map('trim', $url);
        $url['port'] = (!isset($url['port'])) ? 80 : (int)$url['port'];
        $path = (isset($url['path'])) ? $url['path'] : '';

        if ($path == '') {
            $path = '/';
        }

        $path .= ( isset ( $url['query'] ) ) ? "?$url[query]" : '';



        if ( isset ( $url['host'] ) AND $url['host'] != gethostbyname ( $url['host'] ) ) {
            if ( PHP_VERSION >= 5 ) {
                $headers = get_headers("$url[scheme]://$url[host]:$url[port]$path");
            }
            else {
                $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, 30);

                if ( ! $fp ) {
                    return false;
                }
                fputs($fp, "HEAD $path HTTP/1.1\r\nHost: $url[host]\r\n\r\n");
                $headers = fread ( $fp, 128 );
                fclose ( $fp );
            }
            $headers = ( is_array ( $headers ) ) ? implode ( "\n", $headers ) : $headers;
            return ( bool ) preg_match ( '#^HTTP/.*\s+[(200|301|302)]+\s#i', $headers );
        }

        return false;
    }

Merhaba, bu çözüm iyi ve ona oy verdim, ancak https için standart bağlantı noktasını hesaba katmıyor: - bağlantı noktasının çalıştığı yerde 80'i '' ile değiştirmenizi öneririz
pgee70

Bunun üzerine bir varyasyon uyguladım çünkü etki alanım bir URL'nin gerçekten var olup olmadığı umurunda :)
Raz0rwire

2

Inspired bu .NET bir StackOverflow soru ve bu soruya bu başvurulan makalesinde (URI o URL ve URN hem doğrular anlamına gelir) bu URI Doğrulayıcı yoktur.

if( ! preg_match( "/^([a-z][a-z0-9+.-]*):(?:\\/\\/((?:(?=((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9A-F]{2})*))(\\3)@)?(?=(\\[[0-9A-F:.]{2,}\\]|(?:[a-z0-9-._~!$&'()*+,;=]|%[0-9A-F]{2})*))\\5(?::(?=(\\d*))\\6)?)(\\/(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/]|%[0-9A-F]{2})*))\\8)?|(\\/?(?!\\/)(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/]|%[0-9A-F]{2})*))\\10)?)(?:\\?(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9A-F]{2})*))\\11)?(?:#(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9A-F]{2})*))\\12)?$/i", $uri ) )
{
    throw new \RuntimeException( "URI has not a valid format." );
}

Adlandırdığım Urive tarafından test edildiğim bir ValueObject içinde bu işlevi başarıyla birim test ettim UriTest.

UriTest.php (Hem URL'ler hem de URN'ler için geçerli ve geçersiz durumlar içerir)

<?php

declare( strict_types = 1 );

namespace XaviMontero\ThrasherPortage\Tests\Tour;

use XaviMontero\ThrasherPortage\Tour\Uri;

class UriTest extends \PHPUnit_Framework_TestCase
{
    private $sut;

    public function testCreationIsOfProperClassWhenUriIsValid()
    {
        $sut = new Uri( 'http://example.com' );
        $this->assertInstanceOf( 'XaviMontero\\ThrasherPortage\\Tour\\Uri', $sut );
    }

    /**
     * @dataProvider urlIsValidProvider
     * @dataProvider urnIsValidProvider
     */
    public function testGetUriAsStringWhenUriIsValid( string $uri )
    {
        $sut = new Uri( $uri );
        $actual = $sut->getUriAsString();

        $this->assertInternalType( 'string', $actual );
        $this->assertEquals( $uri, $actual );
    }

    public function urlIsValidProvider()
    {
        return
            [
                [ 'http://example-server' ],
                [ 'http://example.com' ],
                [ 'http://example.com/' ],
                [ 'http://subdomain.example.com/path/?parameter1=value1&parameter2=value2' ],
                [ 'random-protocol://example.com' ],
                [ 'http://example.com:80' ],
                [ 'http://example.com?no-path-separator' ],
                [ 'http://example.com/pa%20th/' ],
                [ 'ftp://example.org/resource.txt' ],
                [ 'file://../../../relative/path/needs/protocol/resource.txt' ],
                [ 'http://example.com/#one-fragment' ],
                [ 'http://example.edu:8080#one-fragment' ],
            ];
    }

    public function urnIsValidProvider()
    {
        return
            [
                [ 'urn:isbn:0-486-27557-4' ],
                [ 'urn:example:mammal:monotreme:echidna' ],
                [ 'urn:mpeg:mpeg7:schema:2001' ],
                [ 'urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66' ],
                [ 'rare-urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66' ],
                [ 'urn:FOO:a123,456' ]
            ];
    }

    /**
     * @dataProvider urlIsNotValidProvider
     * @dataProvider urnIsNotValidProvider
     */
    public function testCreationThrowsExceptionWhenUriIsNotValid( string $uri )
    {
        $this->expectException( 'RuntimeException' );
        $this->sut = new Uri( $uri );
    }

    public function urlIsNotValidProvider()
    {
        return
            [
                [ 'only-text' ],
                [ 'http//missing.colon.example.com/path/?parameter1=value1&parameter2=value2' ],
                [ 'missing.protocol.example.com/path/' ],
                [ 'http://example.com\\bad-separator' ],
                [ 'http://example.com|bad-separator' ],
                [ 'ht tp://example.com' ],
                [ 'http://exampl e.com' ],
                [ 'http://example.com/pa th/' ],
                [ '../../../relative/path/needs/protocol/resource.txt' ],
                [ 'http://example.com/#two-fragments#not-allowed' ],
                [ 'http://example.edu:portMustBeANumber#one-fragment' ],
            ];
    }

    public function urnIsNotValidProvider()
    {
        return
            [
                [ 'urn:mpeg:mpeg7:sch ema:2001' ],
                [ 'urn|mpeg:mpeg7:schema:2001' ],
                [ 'urn?mpeg:mpeg7:schema:2001' ],
                [ 'urn%mpeg:mpeg7:schema:2001' ],
                [ 'urn#mpeg:mpeg7:schema:2001' ],
            ];
    }
}

Uri.php (Değer Nesnesi)

<?php

declare( strict_types = 1 );

namespace XaviMontero\ThrasherPortage\Tour;

class Uri
{
    /** @var string */
    private $uri;

    public function __construct( string $uri )
    {
        $this->assertUriIsCorrect( $uri );
        $this->uri = $uri;
    }

    public function getUriAsString()
    {
        return $this->uri;
    }

    private function assertUriIsCorrect( string $uri )
    {
        // /programming/30847/regex-to-validate-uris
        // http://snipplr.com/view/6889/regular-expressions-for-uri-validationparsing/

        if( ! preg_match( "/^([a-z][a-z0-9+.-]*):(?:\\/\\/((?:(?=((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9A-F]{2})*))(\\3)@)?(?=(\\[[0-9A-F:.]{2,}\\]|(?:[a-z0-9-._~!$&'()*+,;=]|%[0-9A-F]{2})*))\\5(?::(?=(\\d*))\\6)?)(\\/(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/]|%[0-9A-F]{2})*))\\8)?|(\\/?(?!\\/)(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/]|%[0-9A-F]{2})*))\\10)?)(?:\\?(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9A-F]{2})*))\\11)?(?:#(?=((?:[a-z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9A-F]{2})*))\\12)?$/i", $uri ) )
        {
            throw new \RuntimeException( "URI has not a valid format." );
        }
    }
}

Birim Testlerini Çalıştırma

46 testte 65 iddia var. Dikkat: geçerli için 2 veri sağlayıcı ve geçersiz ifadeler için 2 tane daha vardır. Biri URL'ler için, diğeri URN'ler içindir. PhpUnit'in v5.6 * veya daha önceki bir sürümünü kullanıyorsanız, iki veri sağlayıcıyı tek bir sağlayıcıda birleştirmeniz gerekir.

xavi@bromo:~/custom_www/hello-trip/mutant-migrant$ vendor/bin/phpunit
PHPUnit 5.7.3 by Sebastian Bergmann and contributors.

..............................................                    46 / 46 (100%)

Time: 82 ms, Memory: 4.00MB

OK (46 tests, 65 assertions)

Kod kapsamı

Bu örnek URI denetleyicisinde% 100 kod kapsamı vardır.


2
"/(http(s?):\/\/)([a-z0-9\-]+\.)+[a-z]{2,4}(\.[a-z]{2,4})*(\/[^ ]+)*/i"
  1. (http (s?): //) http: // veya https: // anlamına gelir

  2. ([a-z0-9 -] +.) + => 2.0 [a-z0-9-], herhangi bir az karakteri veya herhangi bir 0-9 veya (-) işareti anlamına gelir)

                 2.1 (+) means the character can be one or more ex: a1w, 
                     a9-,c559s, f)
    
                 2.2 \. is (.)sign
    
                 2.3. the (+) sign after ([a-z0-9\-]+\.) mean do 2.1,2.2,2.3 
                    at least 1 time 
                  ex: abc.defgh0.ig, aa.b.ced.f.gh. also in case www.yyy.com
    
                 3.[a-z]{2,4} mean a-z at least 2 character but not more than 
                              4 characters for check that there will not be 
                              the case 
                              ex: https://www.google.co.kr.asdsdagfsdfsf
    
                 4.(\.[a-z]{2,4})*(\/[^ ]+)* mean 
    
                   4.1 \.[a-z]{2,4} means like number 3 but start with 
                       (.)sign 
    
                   4.2 * means (\.[a-z]{2,4})can be use or not use never mind
    
                   4.3 \/ means \
                   4.4 [^ ] means any character except blank
                   4.5 (+) means do 4.3,4.4,4.5 at least 1 times
                   4.6 (*) after (\/[^ ]+) mean use 4.3 - 4.5 or not use 
                       no problem
    
                   use for case https://stackoverflow.com/posts/51441301/edit
    
                   5. when you use regex write in "/ /" so it come

    "/(http(s?)://)([a-z0-9-]+.)+[az]{2,4}(.[az]{2,4}) (/ [^] + ) / i "

                   6. almost forgot: letter i on the back mean ignore case of 
                      Big letter or small letter ex: A same as a, SoRRy same 
                      as sorry.

Not: Kötü İngilizce için özür dilerim. Benim ülkem onu ​​pek iyi kullanmıyor.


4
Bu sorunun kaç yaşında olduğunu fark ettiniz mi? Lütfen normal ifadenizi açıklayın, zaten bilmeyen kullanıcılar ayrıntılar olmadan onu anlamakta zorlanacaktır.
Nic3500

1

Tamam, bu basit bir normal ifadeden biraz daha karmaşık, ancak farklı url türlerine izin veriyor.

Örnekler:

Bunların tümü geçerli olarak işaretlenmelidir.

function is_valid_url($url) {
    // First check: is the url just a domain name? (allow a slash at the end)
    $_domain_regex = "|^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,})/?$|";
    if (preg_match($_domain_regex, $url)) {
        return true;
    }

    // Second: Check if it's a url with a scheme and all
    $_regex = '#^([a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))$#';
    if (preg_match($_regex, $url, $matches)) {
        // pull out the domain name, and make sure that the domain is valid.
        $_parts = parse_url($url);
        if (!in_array($_parts['scheme'], array( 'http', 'https' )))
            return false;

        // Check the domain using the regex, stops domains like "-example.com" passing through
        if (!preg_match($_domain_regex, $_parts['host']))
            return false;

        // This domain looks pretty valid. Only way to check it now is to download it!
        return true;
    }

    return false;
}

İzin vermek istediğiniz protokoller için bir dizi içi denetim olduğunu unutmayın (şu anda bu listede yalnızca http ve https bulunmaktadır).

var_dump(is_valid_url('google.com'));         // true
var_dump(is_valid_url('google.com/'));        // true
var_dump(is_valid_url('http://google.com'));  // true
var_dump(is_valid_url('http://google.com/')); // true
var_dump(is_valid_url('https://google.com')); // true

Throws: ErrorException: Undefined index: şema protokol belirtilmemişse, daha önce ayarlanıp ayarlanmadığını kontrol etmenizi öneririm.
user3396065

@ user3396065, bunu atan bir örnek girdi sağlayabilir misiniz?
Tim Groeneveld

1

Benim için çalışan en iyi URL Regex:

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

Örnekler:

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

Kaynak: http://urlregex.com/


0

Peter'ın Regex'i birçok nedenden dolayı bana doğru görünmüyor. Alan adında her türlü özel karaktere izin verir ve fazla test etmez.

Frankie'nin işlevi bana iyi görünüyor ve bir işlev istemiyorsanız bileşenlerden iyi bir normal ifade oluşturabilirsiniz, örneğin:

^(http://|https://)(([a-z0-9]([-a-z0-9]*[a-z0-9]+)?){1,63}\.)+[a-z]{2,6}

Test edilmedi ama bence işe yaramalı.

Ayrıca Owen'ın cevabı da% 100 görünmüyor. Normal ifadenin alan kısmını aldım ve bir Regex test aracı http://erik.eae.net/playground/regexp/regexp.html üzerinde test ettim

Şu satırı koydum:

(\S*?\.\S*?)

"regexp" bölümünde ve aşağıdaki satırda:

-hello.com

"örnek metin" bölümü altında.

Sonuç, eksi karakterin geçmesine izin verdi. Çünkü \ S herhangi bir boşluk olmayan karakter anlamına gelir.

Frankie'den gelen normal ifadenin eksi işlediğine dikkat edin çünkü ilk karakter için bu bölüme sahiptir:

[a-z0-9]

Eksi veya başka herhangi bir özel karaktere izin vermez.


0

İşte benim yaptığım yol. Ama normal ifadeden çok emin olmadığım için mentoin yapmak istiyorum. Ama sen çalışmalı :)

$pattern = "#((http|https)://(\S*?\.\S*?))(\s|\;|\)|\]|\[|\{|\}|,|”|\"|'|:|\<|$|\.\s)#i";
        $text = preg_replace_callback($pattern,function($m){
                return "<a href=\"$m[1]\" target=\"_blank\">$m[1]</a>$m[4]";
            },
            $text);

Bu şekilde deseninizde eval işaretçisine ihtiyacınız olmayacak.

Umarım yardımcı olur :)


0

RegEx kullanarak URL Doğrulaması için basit bir sınıf ve ardından etki alanını popüler RBL (Gerçek Zamanlı Kara Delik Listeleri) sunucularında çapraz referanslar:

Yüklemek:

require 'URLValidation.php';

Kullanımı:

require 'URLValidation.php';
$urlVal = new UrlValidation(); //Create Object Instance

domain()Yöntemin parametresi olarak bir URL ekleyin ve dönüşü kontrol edin.

$urlArray = ['http://www.bokranzr.com/test.php?test=foo&test=dfdf', 'https://en-gb.facebook.com', 'https://www.google.com'];
foreach ($urlArray as $k=>$v) {

    echo var_dump($urlVal->domain($v)) . ' URL: ' . $v . '<br>';

}

Çıktı:

bool(false) URL: http://www.bokranzr.com/test.php?test=foo&test=dfdf
bool(true) URL: https://en-gb.facebook.com
bool(true) URL: https://www.google.com

Yukarıda görebileceğiniz gibi, www.bokranzr.com bir RBL aracılığıyla kötü amaçlı web sitesi olarak listelenmiştir, bu nedenle alan adı yanlış olarak döndürülmüştür.



-1

Bunu, bir URL'yi eşleştirmek için en kullanışlı buldum ..

^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$

1
Bu, ile başlayan URL'lerle eşleşecek ftp:mi?
andrewsi

/ ^(https?:\/\/)?([\da-z\.-]+)\.([az\.]{2,6})([\/\w \ .-] *) * \ /? $ /
Shahbaz

-1

Bunun için PHP yerel işlevi vardır:

$url = 'http://www.yoururl.co.uk/sub1/sub2/?param=1&param2/';

if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
    // Wrong
}
else {
    // Valid
}

Filtrelenen verileri döndürür veya filtre başarısız olursa YANLIŞ.

Burada kontrol edin


Bu cevap, 2008'deki cevaplardan birini tekrarlıyor!
şüpheli
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.