preg_replace_callback模式问题

时间:2013-01-19 01:16:36

标签: php regex preg-replace-callback

我正在使用以下模式捕获链接,并将它们转换为HTML友好链接。我在preg_replace_callback中使用以下模式,并且大多数情况下它都有效。

"#(https?|ftp)://(\S+[^\s.,>)\];'\"!?])#"

但是当文本如下所示时,这种模式会失败:

http://mylink.com/page[/b]

此时它捕获[/ b有趣它是链接的一部分,导致这个:

<a href="http://woodmill.co.uk[/b">woodmill.co.uk[/b</a>]

我查看了这个模式,并使用了一些备忘单来尝试跟踪发生的事情,但它让我感到厌恶。你们中的任何一个人都可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

尝试将空心方括号添加到角色类:

(\S+[^\s.,>)[\];'\"!?])
            ^

<强>更新

试试这个更有效的网址正则表达式:

^(https?://)?([\da-z\.-]+)\.([a-z\.]{2,6})([/\w \.-]*)*/?$

(来自:http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/

我没有直接使用PHP正则表达式的经验,但上面的内容很简单和通用,我不希望有任何问题。您可能希望修改它以仅提取域,就像您似乎使用当前的正则表达式一样。

答案 1 :(得分:0)

好的我解决了这个问题。感谢@ Cyborgx37和@MikeBrant的帮助。这是解决方案。

首先,我用JoãoCastro在这个问题中使用的模式替换了我的正则表达式模式:Making a url regex global

该模式的问题是它捕获了最后的任何尾随点,因此在模式的最后一部分我添加了^.,使得最终部分看起来像[^\s^.]。当我读它时,不要匹配尾随空格或点。

如上所述,这仍然导致匹配bbcode的问题,所以我使用preg_replace_callback()和create_function()来过滤掉它。最终的create_function()如下所示:

create_function('$match','
                $match[0] = preg_replace("/\[\/?(.*?)\]/", "", $match[0]);
                $match[0] = preg_replace("/\<\/?(.*?)\>/", "", $match[0]);
                $m = trim(strtolower($match[0]));
                $m = str_replace("http://", "", $m);
                $m = str_replace("https://", "", $m);
                $m = str_replace("ftp://", "", $m);
                $m = str_replace("www.", "", $m);

                if (strlen($m) > 25)
                {
                    $m = substr($m, 0, 25) . "...";
                }

                return "<a href=\"$match[0]\" target=\"_blank\">$m</a>";
'), $string);

到目前为止的测试看起来很好,所以我很高兴它现在已经解决了。

再次感谢,我希望这有助于其他人:)