正则表达式bbcode和字符串的超链接

时间:2015-08-25 13:48:13

标签: php regex bbcode

[url=http://stackoverflow.com]stackoverflow[/url]
[url=http://stackoverflow.com]http://stackoverflow.com[/url]
http://stackoverflow.com
[url=http://stackoverflow.com][img]url_to_img[/img][/url]
[url=http://stackoverflow.com][b]stackoverflow[/b][/url]
[url=http://stackoverflow.com][b][u][i]stackoverflow[/i][/u][/b][/url]
[url=http://stackoverflow.com][color=red]stackoverflow[/color][/url]
[url=http://stackoverflow.com][h1][color=red]stackoverflow[/color][/h1][/url]

将其更改为:

<a href="http://stackoverflow.com">stackoverflow</a>
<a href="http://stackoverflow.com">http://stackoverflow.com</a>
<a href="http://stackoverflow.com">http://stackoverflow.com</a>
<a href="http://stackoverflow.com"><img src="url_to_img" /></a>
<a href="http://stackoverflow.com"><strong>stackoverflow</strong></a>
<a href="http://stackoverflow.com"><span style="color:red">stackoverflow</span></a>
<a href="http://stackoverflow.com"><h1><span style="color:red">stackoverflow</span></h1></a>

我试着找到一些替代所有不是bbcode网址的东西 我尝试使用https://github.com/wookieb/bbcode但是当我升级php 5.2到5.5时停止工作 我尝试使用http://jbbcode.com/但不解析字符串中的url。

1 个答案:

答案 0 :(得分:1)

我重建了除一行以外的所有行,只有一行。

<?php
$input = "[url=http://stackoverflow.com]stackoverflow[/url]
[url=http://stackoverflow.com]http://stackoverflow.com/damn[/url]
http://stackoverflow.com/ok
[url=http://stackoverflow.com][img]url_to_img[/img][/url]
[url=http://stackoverflow.com][b]stackoverflow[/b][/url]
[url=http://stackoverflow.com][b][u][i]stackoverflow[/i][/u][/b][/url]
[url=http://stackoverflow.com][color=red]stackoverflow[/color][/url]
[url=http://stackoverflow.com][h1][color=red]stackoverflow[/color][/h1][/url]";

$match = [
    '/\[url=([^\]]+)\](.*)\[\/url\]/im',
    '/\[img\](.*)\[\/img\]/im',
    '/\[b\](.*)\[\/b\]/im',
    '/\[u\](.*)\[\/u\]/im',
    '/\[i\](.*)\[\/i\]/im',
    '/\[color=([^\]]+)\](.*)\[\/color\]/im',
    '/\[h([1-6])\](.*)\[\/h(?:[1-6])\]/im',
];
$replace = [
    '<a href="$1">$2</a>',
    '<img src="$1">',
    '<strong>$1</strong>',
    '<u>$1</u>',
    '<em>$1</em>',
    '<span style="color:$1;">$2</span>',
    '<h$1>$2</h$1>',
];

echo preg_replace($match, $replace, $input);

这提供了以下输出:

<a href="http://stackoverflow.com">stackoverflow</a>
<a href="http://stackoverflow.com">http://stackoverflow.com/damn</a>
http://stackoverflow.com/ok
<a href="http://stackoverflow.com"><img src="url_to_img"></a>
<a href="http://stackoverflow.com"><strong>stackoverflow</strong></a>
<a href="http://stackoverflow.com"><strong><u><em>stackoverflow</em></u></strong></a>
<a href="http://stackoverflow.com"><span style="color:red;">stackoverflow</span></a>
<a href="http://stackoverflow.com"><h1><span style="color:red;">stackoverflow</span></h1></a>

只匹配网址的那个有点棘手。这取决于你想要的高级程度。它可能会检测到诸如example.com之类的简单内容或更高级的内容,例如☃.net(导致http://xn--n3h.net/

一些解释
我们尝试匹配和替换的第一条规则是网址代码。我们通过搜索简单和硬编码的[url=的外观来简单地开始。我们接下来要寻找的东西可能是很多东西,但我们肯定知道的一件事是我们必须以]结尾。然后,我们可以使用正则表达式:match all but ] ([^\]]+)请注意,我转义了]字符,否则匹配将失败。
接下来,我再次搜索所有内容((.*)),直到我们达到硬编码的预期值[/url]。 这几乎是你想要的每种类型bbcode的完整匹配规则。

对于替换部件,您应该包含它们应该替换的内容,简单。要添加正则表达式中匹配的值,请使用$1, $2, ..., $n。匹配由我的括号定义 举个例子:'/ [url = ([^]] +)](.*) [/ url] / im'
以粗体显示的两个括号段是包含我们将从$1$2

获取的值的细分

我尽力解释这是如何运作的。如果某些事情仍然不清楚,请指出,我将尽力进一步解释