2012-03-28 103 views
1

我需要一個函數來檢查字符串中的現有URL。正則表達式匹配大多數URL需要改進

function linkcleaner($url) { 
$regex="(?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`!()\[\]{};:'".,<>?«»「」‘’]))"; 

if(preg_match($regex, $url, $matches)) { 
echo $matches[0]; 
} 
} 

正則表達式從John Gruber's blog,在那裏他討論創建一個正則表達式匹配的所有URL的問題而採取的。 不幸的是,我不能讓它工作。看起來問題來自正則表達式中的雙引號或表達式末尾的其他點符號。 任何幫助表示讚賞。 謝謝!

+10

「不能使它工作「不是內置的PHP錯誤信息。 – 2012-03-28 16:38:25

+2

@JackManey,roflmao – 2012-03-28 16:50:30

+0

對不起,錯誤是「Parse error:syntax error,unexpected','在C:\ ... \ config.php on line ...」。英語不是我的母語,有時我解釋我想說的話有問題。 – olegb3 2012-03-28 17:06:51

回答

2

除了@ tandu的回答,你還需要在php中使用正則表達式的分隔符。

最簡單的將是開始和結束與#你的模式,即文字沒有出現在它:

$regex="#(?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`!()\[\]{};:\'\".,<>?«»「」‘’]))#"; 
+0

編輯了我的答案,使用'#「可能是url的一部分(指定主播)... – poncha 2012-03-28 17:10:04

+0

謝謝!我怎麼會錯過那個...救了我的一天:) – olegb3 2012-03-28 17:10:55

+0

@poncha它不會出現在這個正則表達式模式中,那是唯一重要的東西。 – jeroen 2012-03-28 17:16:17

3

你需要躲避"\

1

傑克·梅尼的評論... EPIC:d

在一個更嚴重的是,這是行不通的,因爲你終止在中間的字符串字面權。

要在字符串中的雙引號("),您需要使用\

所以逃吧,行會

$regex="/(?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`!()\[\]{};:\'\".,<>?«»「」‘’]))/"; 

通知我躲過了(')以及。這是爲了在兩個單引號之間定義一個字符串。

+0

謝謝@tandu 我仍然收到一個錯誤警告:preg_match()[function.preg-match]:未知修飾符'\'在C:\ wamp \ www \ ... \ config.php上919行 – olegb3 2012-03-28 17:01:23

+0

I想想在PHP中,你需要在開始和結束時用相同的字符分隔正則表達式。我使用'/' – 2012-03-29 03:34:29

1

我不知道你們怎麼看這個表達式,因爲它是一個真正的痛苦讀取/修改...;)

試試這個(這不是一個班輪,是的,但很容易理解,如果需要修改):

<?php 
$re_proto = "(?:https?|ftp|gopher|irc|whateverprotoyoulike)://"; 
$re_ipv4_segment = "[12]?[0-9]{1,2}"; 
$re_ipv4 = "(?:{$re_ipv4_segment}[.]){3}".$re_ipv4_segment; 
$re_hostname = "[a-z0-9_]+(?:[.-][a-z0-9_]+){0,}"; 
$re_hostname_fqdn = "[a-z0-9_](?:[a-z0-9_-]*[.][a-z0-9]+){1,}"; 
$re_host = "(?:{$re_ipv4}|{$re_hostname})"; 
$re_host_fqdn = "(?:{$re_ipv4}|{$re_hostname_fqdn})"; 
$re_port = ":[0-9]+"; 
$re_uri = "(?:/[a-z0-9_.%-]*){0,}"; 
$re_querystring = "[?][a-z0-9_.%&=-]*"; 
$re_anchor = "#[a-z0-9_.%-]*"; 
$re_url = "(?:(?:{$re_proto})(?:{$re_host})|{$re_host_fqdn})(?:{$re_port})?(?:{$re_uri})?(?:{$re_querystring})?(?:{$re_anchor})?"; 

$text = <<<TEXT 
http://www.example.com 
http://www.example.com/some/path/to/file.php?f1=v1&f2=v2#foo 
http://localhost.localdomain/ 
http://localhost/docs/??? 
www....wwhat? 
www.example.com 
ftp://ftp.mozilla.org/pub/firefox/latest/ 
Some new Mary-Kate Olsen pictures I found: the splendor of the Steiner Street Picture of href… http://t.co/tJ2NJjnf 
TEXT; 

$count = preg_match_all("\01{$re_url}\01is", $text, $matches); 
var_dump($count); 
var_dump($matches); 
?> 
+0

你的答案是greate!這是唯一正則表達式正確解析以下字符串:'RT @JustBrelieve:「@ enn4xor:#TBT去年夏天。 * _ * http://t.co/LsasKwfe「你可愛,你可愛。' – Oleg 2012-07-26 08:58:08

+0

我發現了一些問題'$ re_hostname_fqdn'參數。它匹配'瑪麗 - 凱特'作爲URL在'我發現一些新的瑪麗 - 凱特奧爾森圖片:輝煌的斯坦納街圖片href ... http:// t.co/tJ2NJjnf' – Oleg 2012-07-26 09:12:59

+0

@Oleg'$ re_hostname_fqdn'會匹配'瑪麗 - 凱特',因爲它是一個可能的主機名(如任何單詞......),但它爲什麼匹配無原型...我會研究這個,感謝注意 – poncha 2012-07-26 10:52:12