2

我目前正在尝试从 BBCode 获取 URL。它有四种可能性,这是我目前的问题:

[url]http://stackoverflow.com/[/url]
[url='http://stackoverflow.com/']http://stackoverflow.com/[/url]
[url="http://stackoverflow.com/"]http://stackoverflow.com/[/url]
[url=http://stackoverflow.com/]http://stackoverflow.com/[/url]

我两个都需要。这就是我到目前为止所拥有的:

/\[url(?:\=\'([^\'"]+)\')?](.+?)\[\/url]/i

但这仅适用于案例 1 和 2。

编辑:

这效果更好:

/\[url(?:\=(?:[\"|'])?(.*)(?:[^[]+)?)?\](.*)\[\/url\]/i

但仍然不完美。

编辑:

我想,我明白了。它可能需要一些优化,但它似乎工作:

/\[url(?:\=("|\'|)?(.*)?\1)?\](.*)\[\/url\]/i

正则表达式测试器

4

2 回答 2

4

您可以使用此模式:

$pattern = '~\[url(?|=[\'"]?([^]"\']+)[\'"]?]([^[]+)|](([^[]+)))\[/url]~';
$replacement = '<a href="$1">$2</a>';

$result = preg_replace($pattern, $replacement, $subject);

这个想法是使用分支重置功能为交替的每个分支保留组编号。这样,第 1 组始终包含 url,第 2 组始终包含链接描述。当没有描述时,会使用 url,这就是为什么 url 两次包含在第二个分支的捕获组中。

于 2013-07-07T01:04:59.840 回答
0

试试这个,它会工作

<?php
  $urlsearch  = "(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?";
  $text = preg_replace( "/\[url\]($urlsearch)\[\/url\]/", "<a href=\"$1\">$1</a>", $text );
  $text = preg_replace( "(\[url\=[\"']?($urlsearch)[\"']?\](.+?)\[/url\])", "<a href=\"$1\">$5</a>", $text );

  print_r( $text );
?>
于 2013-07-06T23:40:22.053 回答