2012-05-13 59 views
6
$pattern = "/\[(.*?)\]\((.*?)\)/i"; 
$replace = "<a href=\"$2\" rel=\"nofollow\">$1</a>"; 
$text = "blah blah [LINK1](http://example.com) blah [LINK2](http://sub.example.com/) blah blah ?"; 
echo preg_replace($pattern, $replace, $text); 

上述作品,但如果空間[]和()一切休息和兩個鏈接都混爲一體之間意外插入:爲什麼我的PHP解析Markdown鏈接的正則表達式被破壞?

$text = "blah blah [LINK1] (http://example.com) blah [LINK2](http://sub.example.com/) blah blah ?"; 

我有一種感覺它的laxy明星,打破它但不知道如何匹配重複鏈接。

+0

之間添加這是某種形式的降價解析器?如果是這樣,爲什麼不使用現有的? – Gumbo

+0

它是。我只需要基本的鏈接功能,而不需要ID和標題。 – user1070125

回答

7

如果我理解你的權利,你需要做的確實也匹配任意數量的兩者之間的空間爲好,例如:

/\[([^]]*)\] *\(([^)]*)\)/i 

說明:

\[    # Matches the opening square bracket (escaped) 
([^]]*)  # Captures any number of characters that aren't close square brackets 
\]    # Match close square bracket (escaped) 
*    # Match any number of spaces 
\(   # Match the opening bracket (escaped) 
([^)]*)  # Captures any number of characters that aren't close brackets 
\)    # Match the close bracket (escaped) 

理由:

我應該證明我之所以把你的.*?改成[^]]*

第二個版本效率更高,因爲它不需要執行大量的.*?回溯。此外,一旦遇到開頭[.*?版本將繼續查找,直到它找到匹配,而不是失敗,如果它不是我們想要的標籤。例如,如果我們使用.*?對匹配表達式:

Sad face :[ blah [LINK1](http://sub.example.com/) blah 

它將匹配

[ blah [LINK1] 

http://sub.example.com/ 

使用[^]]*方法將意味着輸入正確匹配。

+0

這個人有一個錯字,但我不能解決它,因爲我不知道它應該如何工作。 – user1070125

+0

你是對的,我修復了錯字併爲你添加了一個解釋 – Jarmex

+0

我還添加了爲什麼我將'。*?'改成'[^]]的理由''' – Jarmex

0

試試這個:

$pattern = "/\[(.*?)\]\s?\((.*?)\)/i"; 

\s?\[(.*?)\]\((.*?)\)

+0

這樣的parens不匹配的網址,它以某種方式用於處理單個空間。我認爲最好是要求嚴格標記並忽略其他所有內容(原樣輸出)。 – user1070125