2010-12-08 14 views
12

Próbuję znaleźć niezawodne rozwiązanie do wyodrębnienia adresu URL z ciągu znaków. Mam stronę, na której użytkownicy odpowiadają na pytania iw polu źródłowym, gdzie wpisują swoje źródło informacji, zezwalam im na wpisanie adresu URL. Chcę wyodrębnić ten URL i uczynić go hiperłączem. Podobnie jak robi to Yahoo Answers.Wyodrębnij URL ze stringa

Czy ktoś zna niezawodne rozwiązanie, które może to zrobić?

Wszystkie znalezione przeze mnie rozwiązania działają dla niektórych URL-i, ale nie dla innych.

Dzięki

Odpowiedz

22

John Gruber ma spent a fair amount of time Doskonalenie „jeden regex by wszystkimi rządzić” do wykrywania łącza. Korzystanie preg_replace() jak wspomniano w innych odpowiedzi, używając następującego wyrażenia regularnego powinno być jednym z najbardziej dokładne, jeśli nie jest to najbardziej dokładna metoda wykrywania link:

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

Gdybyś tylko chciał dopasować HTTP/HTTPS:

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

Dokładnie to, czego szukałem, dziękuję, –

+4

Dla każdego, kto chce, aby wszystkie wzorce podrzędne zostały zamienione, aby nie były przechwytywane, a przekreślone ukośniki: \ b (?: (?: [az] [\ w -] +: (?: \/{1,3} | [a-z0-9%]) | www \ d {0,3 } [.] | [a-z0-9. \ -] + [.] [az] {2,4} \ /) (?: [^ \ s() <>] + | \ ((?: [^\ s() <>] + | (?: \ ([^ \ s() <>] + \))) * \)) + (?: \ ((?: [^ \ s() <> ] + | (?: \ ([^ \ s() <>] + \))) * \) | [^ \ s '!() \ [\] {} ;:" "., <>?« »" "''])) –

+0

Domeny mogą mieć więcej niż 4 znaki, zobacz: http://www.iana.org/domains/root/db – Toto

0

Yahoo! Odpowiedzi wykonuje dość dobrą robotę identyfikacji łącza, gdy link jest napisany poprawnie i oddzielony od innego tekstu, ale nie jest zbyt dobry w oddzielaniu końcowej interpunkcji. Na przykład The links are http://example.com/somepage.php , http://example.com/somepage2.php , and http://example.com/somepage3.php . będzie zawierać przecinki na pierwszych dwóch i kropkę na trzecim.

Ale jeśli jest to dopuszczalne, wówczas wzory jak powinno to zrobić:

\<http:[^ ]+\> 

Wygląda parser StackOverflow jest lepsza. Czy to open source?

+0

mądrzejszy, ale nadal nie doskonały. pomija takie rzeczy jak ssh + svn. – DampeS8N

3
$string = preg_replace('/https?:\/\/[^\s"<>]+/', '<a href="$0" target="_blank">$0</a>', $string); 

Pasuje tylko do http/https, ale to naprawdę jedyny protokół, który chcesz zamienić w łącze. Jeśli chcesz, aby inni, można zmienić to tak:

$string = preg_replace('/(https?|ssh|ftp):\/\/[^\s"]+/', '<a href="$0" target="_blank">$0</a>', $string); 
+1

Możesz również wykluczyć '<' lub zastosować 'htmlspecialchars' na dopasowanym łańcuchu, aby uniknąć wtrysku kodu. – Gumbo

+0

Dobrze, ale jeśli spojrzysz na wyrażenie, to pozwala na wszystko poza białą przestrzenią i "". Wierzę, że eliminuje zastrzyki HTML – Jonah

+1

Bron: Nie, używasz dopasowanej wartości nie tylko jako wartości atrybutu, ale także jako zawartość tekstowa elementów: – Gumbo

-1

Ten kod jest przeznaczony dla mnie.

function makeLink($string){ 

/*** make sure there is an http:// on all URLs ***/ 
$string = preg_replace("/([^\w\/])(www\.[a-z0-9\-]+\.[a-z0-9\-]+)/i", "$1http://$2",$string); 
/*** make all URLs links ***/ 
$string = preg_replace("/([\w]+:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/i","<a target=\"_blank\" href=\"$1\">$1</a>",$string); 
/*** make all emails hot links ***/ 
$string = preg_replace("/([\w-?&;#~=\.\/]+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?))/i","<a href=\"mailto:$1\">$1</a>",$string); 

return $string; 
} 
+1

Dlaczego ograniczasz tld do 3 znaków? Zajrzyj na: http://www.iana.org/domains/root/db – Toto

Powiązane problemy