为什么我的PHP正则表达式会解析Markdown链接?

时间:2012-05-13 11:27:18

标签: php regex markdown

$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);

上述方法有效但如果在[]和()之间意外插入空格,一切都会中断,两个链接混合成一个:

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

我有一种感觉,这是一个松散的明星打破它,但不知道如何匹配重复的链接。

2 个答案:

答案 0 :(得分: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/

使用[^]]*方法意味着输入正确匹配。

答案 1 :(得分:0)

试试这个:

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

之间添加了

\((.*?)\)