2012-09-21 32 views
0

下面的代碼檢查任何URL的字符串中的文本並將它們轉換爲可點擊的鏈接。正則表達式用鏈接替換url並添加特定的rel

我試圖獲得它,以便如果有圖像鏈接,它會在< a>標記中添加rel =「image」。如果有YouTube視頻,它會將rel =「youtube」添加到< a>標籤。

如果字符串中只有一個鏈接,它工作正常。當有多個鏈接時,所有鏈接都會獲得最後一個鏈接的相關信息。

$text = "http://site.com a site www.anothersite.com/ http://imgur.com/image.png http://youtu.be/UyxqmghxS6M here is another site"; 

$linkstring = preg_replace('/(http|ftp)?+(s)?:?(\/\/)?+(www.)?((\w|\.)+)+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU|be|info|co)+(\/)?(\S+)?/i', '<a rel="iframe" href="\0">\0</a>', $text); 
if(preg_match('/((http:\/\/)?(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/v\/)([\w-]{11}).*|http:\/\/(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/watch(?:\?|#\!)v=)([\w-]{11}).*)/i', $linkstring, $vresult)) { 
    $pattern = "/(http|ftp)?+(s)?:?(\/\/)?+(www.)?((\w|\.)+)+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU|be|info|co)+(\/)?(\S+)?/i"; 
    $replacement = '<a rel="youtube" href="\0">\0</a>'; 
    $text2 = preg_replace($pattern, $replacement, $text); 
    $type= 'youtube'; 
} elseif(preg_match('/(http(s?):)?|([\/|.|\w|\s])*\.(?:jpg|gif|png|jpeg|bmp)/i', $linkstring, $vresult)) { 
    $pattern = "/(http|ftp)?+(s)?:?(\/\/)?+(www.)?((\w|\.)+)+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU|be|info|co)+(\/)?(\S+)?/i"; 
    $replacement = '<a rel="image" href="\0">\0</a>'; 
    $text2 = preg_replace($pattern, $replacement, $text); 
    $type= 'image'; 
} else { 
    $type = 'none'; 
} 
echo $text, "<br />"; 
echo $text2, "<br />"; 
echo $linkstring, "<br />"; 
echo $type, "<br />"; 

我試圖改變$模式以便它匹配相同的正則表達式的YouTube或圖片鏈接,但它結束了創建鏈接的URL後的全部文本。

例子:

$text = "http://site.com a site www.anothersite.com/ http://imgur.com/image.png http://youtu.be/UyxqmghxS6M here is another site"; 

$linkstring = preg_replace('/(http|ftp)?+(s)?:?(\/\/)?+(www.)?((\w|\.)+)+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU|be|info|co)+(\/)?(\S+)?/i', '<a rel="iframe" href="\0">\0</a>', $text); 
if(preg_match('/((http:\/\/)?(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/v\/)([\w-]{11}).*|http:\/\/(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/watch(?:\?|#\!)v=)([\w-]{11}).*)/i', $linkstring, $vresult)) { 
    $pattern = "/((http:\/\/)?(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/v\/)([\w-]{11}).*|http:\/\/(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/watch(?:\?|#\!)v=)([\w-]{11}).*)/i"; 
    $replacement = '<a rel="youtube" href="\0">\0</a>'; 
    $text2 = preg_replace($pattern, $replacement, $text); 
    $type= 'youtube'; 
} else { 
    $type = 'none'; 
} 

回答

0

不幸的是,我不能讓你的正則表達式的工作,就看你的輸出看起來完全像什麼(它可能如果幫助,如果您發佈的生成的字符串,而不是僅僅描述它們)。

但是,您所做的是以下內容。在if語句的第一個片段中,檢查字符串是否包含YouTube鏈接或圖像鏈接。但是,你根本不使用這些信息,而只是在整個初始字符串中再次使用preg_replace。哪一個當然會取代所有的鏈接,而不僅僅是你之前用preg_match發現的鏈接(因爲這個調用是完全不相關的)。

所以你的第二種方法實際上更好。雖然,在這種情況下,我不認爲你需要if-clause,因爲只有字符串部分會被替換爲匹配相同的模式。你在鏈接後得到完整字符串的原因是RegExes中的所謂貪婪。這是因爲您使用.*結束了兩種可能的YouTube模式。這可能會導致與URL的其餘部分相匹配,但它總是會盡可能多地接受。並且由於.與任何字符匹配,即字符串的其餘部分。所以首先,你需要告訴正則表達式在哪裏停止考慮字符。例如,您可以說網址以空格或引號結尾。因此,而不是

(youtubepattern1).*|(youtubepattern2).* 

你可以嘗試

((youtubepattern1|youtubepattern2).*)["\s] 

但現在貪仍然是一個問題,如果在後面的字符串的URL或進一步空格之後是超過一個引號(因爲那麼它將包括一切,直到最後一個空格或引號)。 (在PHP中的正則表達式的方法)來告訴解釋治療* ungreedily,添加一個問號:

((youtubepattern1|youtubepattern2).*?)["\s] 

此外,您可能會需要您更換使用\0改爲使用\1現在(因爲\ 0會包括結束URL的空格或引號)。