【问题标题】:Why is my PHP regex that parses Markdown links broken?为什么我解析 Markdown 链接的 PHP 正则表达式被破坏了?
【发布时间】:2012-05-21 05:29:30
【问题描述】:
$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 ?";

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

【问题讨论】:

  • 这是某种 Markdown 解析器吗?如果是这样,你为什么不使用一个已经存在的?
  • 是的。我只需要基本的链接功能,不需要id和title。

标签: php regex markdown


【解决方案1】:

如果我理解你的话,你真正需要做的就是匹配两者之间的任意数量的空格,例如:

/\[([^]]*)\] *\(([^)]*)\)/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/

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

【讨论】:

  • 这个有错字,但我无法修复它,因为我不确定它应该如何工作。
  • 你是对的,我已经修正了错字并为你添加了解释
  • 我还添加了为什么我将.*? 更改为[^]]* 的理由
  • 我明白你的意思,但 [^]]* 匹配结束 ] 并且你的“悲伤的脸”示例仍然会失败。
  • 不匹配带括号的 URL,例如 en.wikipedia.org/wiki/Toast_(computing)
【解决方案2】:

试试这个:

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

\s? 添加在 \[(.*?)\]\((.*?)\) 之间

【讨论】:

  • 以某种方式处理一个单独的空间。我认为最好要求严格标记并忽略其他所有内容(按原样输出)。
猜你喜欢
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-16
相关资源
最近更新 更多