Kimsenin iyi çalışıyor kullanışlı bir tane var, URL için basit bir regex arıyorum? Ben zend framework doğrulama sınıfları ile birini bulamadık ve çeşitli uygulamaları gördük.
Teşekkürler
i birkaç proje üzerinde bu kullanılan, i sorunları çalıştırmak inanmıyorum, ama ayrıntılı değil eminim:
$text = preg_replace("
#((http|https|ftp)://(\S*?\.\S*?))(\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)#ie",
"'<a href=\"$1\" target=\"_blank\">$3</a>$4'",
$text
);
sonunda rastgele önemsiz çoğu (sondaki dönemi eşleşen önlemek için) bir sentance http://domain.com.
gibi durumlarla başa çıkmak için. Ben o kadar temizlenmiş olabilir emin değilim ama o amele beri ben daha fazla veya daha az sadece projeden projeye üzerinden kopyalanan ettik.
PHP kılavuzuna göre - parse_url not bir URL doğrulamak için kullanılmalıdır.
Ne yazık ki, o filter_var('example.com', FILTER_VALIDATE_URL)
daha iyi yapmaz gibi görünüyor.
Her iki parse_url()
ve filter_var()
gibi http://...
olarak hatalı biçimlendirilmiş URL'lerin geçecek
Bu nedenle, bu durumda - regex is iyi bir yöntem.
Sadece durumda url gerçekten varsa bilmek istiyorum:
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);
}
Ben normal ifadeler kullanarak bu durumda yapılacak akıllı bir şey olduğunu sanmıyorum. Bu olasılıkların her maç için imkansız ve hatta eğer, url basitçe yok ki hala bir şans var.
İşte url aslında mevcut ve okunabilir olup olmadığını test etmek için çok basit bir yoludur:
if (preg_match("#^https?://.+#", $link) and @fopen($link,"r")) echo "OK";
(Varsa no preg_match
bu da sunucu üzerindeki tüm dosya adları doğrulamak olurdu)
John Gruber (Daring Fireball) başı olarak:
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)
İşte (yorumlarla) genişletilmiş regex desen:
(?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
)
)
For more details please look at: http://daringfireball.net/2010/07/improved_regex_for_matching_urls
Edit:
As incidence pointed out this code has been DEPRECATED with the release of PHP 5.3.0 (2009-06-30) and should be used accordingly.
Sadece benim iki kuruş ama bu işlevi geliştirdik ve başarı ile bir süre kullanıyoruz. Kolayca değiştirmek, böylece iyi belgelenmiş ve ayrı.
// 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;
}
Ve cevabı yoktur =) bunu kırmaya çalışın, bunu 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 ...
"æ", // æ
"Æ", // Æ
"À", // À
"à", // à
"Á", // Á
"á", // á
"Â", // Â
"â", // â
"å", // å
"Å", // Å
"ä", // ä
"Ä", // Ä
"Ç", // Ç
"ç", // ç
"Ð", // Ð
"ð", // ð
"È", // È
"è", // è
"É", // É
"é", // é
"Ê", // Ê
"ê", // ê
"Ë", // Ë
"ë", // ë
"Î", // Î
"î", // î
"Ï", // Ï
"ï", // ï
"ø", // ø
"Ø", // Ø
"ö", // ö
"Ö", // Ö
"Ô", // Ô
"ô", // ô
"Õ", // Õ
"õ", // õ
"Œ", // Œ
"œ", // œ
"ü", // ü
"Ü", // Ü
"Ù", // Ù
"ù", // ù
"Û", // Û
"û", // û
"Ÿ", // Ÿ
"ÿ", // ÿ
"Ñ", // Ñ
"ñ", // ñ
"þ", // þ
"Þ", // Þ
"ý", // ý
"Ý", // Ý
"¿", // ¿
)), ENT_QUOTES, 'UTF-8');
$LINK_ICHARS = $LINK_ICHARS_DOMAIN . (string) html_entity_decode(implode("", array(
"ß", // ß
)), 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;
}
Ben başarı iyi bir oran ile oldukça bir süre için bunu kullandı:
(?:(?:ht|f)tps?://)*(?:[a-zA-Z0-9-]+\\.)+(?:com|net|org|info|mil|gov|edu|name|xxx|[a-z]{2}){1}(?::[0-9]+)?(?![a-z])(?:/[a-zA-Z0-9\\^\\.\\{\\}\\(\\)\\[\\]_\\?,'/\\\\+&%\\$:#=~-]*)*
Birkaç yıldır kullanımda oldu bu yana olsa da bazı yeni TLD'lerin için güncelleştirilmesi gerekebilir.
Peter Regex birçok nedenden dolayı bana doğru görünmüyor. Bu etki alanı adı özel karakterler her türlü olanak ve çok için test etmez.
Frankie fonksiyonu bana iyi görünüyor ve size bir işlev istemiyorsanız bileşenleri iyi bir regex inşa gibi pek yapabilirsiniz:
^(http://|https://)(([a-z0-9]([-a-z0-9]*[a-z0-9]+)?){1,63}\.)+[a-z]{2,6}
Denenmemiş ama bu çalışması gerektiğini düşünüyorum.
Ayrıca, Owen'ın cevabı da% 100 görünmüyor. Ben regex bir etki yer aldı ve bir Regex test aracı üzerinde test http://erik.eae.net/playground/regexp/regexp.html
Ben aşağıdaki satırı koyun:
(\S*?\.\S*?)
in the "regexp" section and the following line:
-Hello.com
"örnek metin" bölümünde.
Sonuç yoluyla eksi karakteri izin verdi. \ S herhangi boşluk olmayan bir karakter anlamına gelir çünkü.
Bu ilk karakter için bu bölümü çünkü Frankie gelen regex eksi kolları Not:
[a-z0-9]
Eksi ya da herhangi başka bir özel karakter izin vermez Hangi.
Tamam, bu daha sonra basit bir regex biraz daha karmaşık, ama bu adresler farklı türleri için izin verir.
Örnekler:
Geçerli işaretlenmiş gereken tüm.
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;
}
Izin vermek istediğiniz protokoller için bir in_array'in çek olduğunu unutmayın (hatta geçerli mailto kabul eder:! Şemaları, bazen)