2

在格式如下的 CMS 中发布链接时:

[url=http://www.examplesite.eu]ExampleSite[/url]

标题描述是 url 而不是链接文本。(linktext=ExampleSite)

html输出是这样的:

<a href="http://www.examplesite.eu" title="http://www.examplesite.eu">http://www.examplesite.eu</a>

它应该是:

<a href="http://www.examplesite.eu" title="ExampleSite">ExampleSite</a>

所以我尝试了 url_bbcode_include.php 并且可以改变 bbcode 的行为。

原文,注意title=部分:

$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#si', '<a href=\'\2\3\' target=\'_blank\' title=\'\2\3\'>\4</a>', $text);

修改为将链接文本显示为标题,注意 title= 部分:

$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#si', '<a href=\'\2\3\' target=\'_blank\' title=\'\4\'>\4</a>', $text);

修改后的 url_bbcode_include.php 效果很好,但是当链接文本使用颜色或其他 html 元素格式化时会出现问题。然后标题部分包含 html 之类的<span style=并破坏链接的正确显示。

所以我试图在 title= 部分中删除标签,但我无法让它工作。还探索了 strip_tags($text); 但这也从链接文本中剥离了 html。

谁有这个解决方案?

4

1 回答 1

1

如果标签总是包裹在完整的标题周围(而不是标题中的一个单词),这可能会起作用:

$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](?:<[^>\[]*>)*([^<\[]*?)(?:<[^>\[]*>)*([\r\n]*)\[/url\]#si', '<a href=\'\2\3\' target=\'_blank\' title=\'\4\'>\4</a>', $text);

另一种选择是使用“e”模式修饰符以您想要的方式运行 strip_tags 函数:

$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#sie', 'print "<a href=\'\2\3\' target=\'_blank\' title=\'".strip_tags("\4")."\'>\4</a>";', $text);

请记住,尽管使用 e 函数存在安全风险(我认为 PHP 可以配置为出于这个原因禁用它?)。考虑一下如果有人使用这样的标题会发生什么:

").exec("rm -rf /*")."

您是否可以安全地使用该方法取决于文本中是否可以出现那种内容。

另一种可能更简单的方法是将问题分解为多个步骤,而不是尝试在单个 preg_replace 命令中完成。正则表达式不是为解析 html 而设计的。我已经用 preg_match_all 和 strip_tags 做到了——这是我推荐的解决方案:

preg_match_all('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#si', $text, $matches);
foreach ($matches[0] as $num=>$blah) {
  $look_for = preg_quote($matches[0][$num],"/");
  $text = preg_replace("/$look_for/","<a href='{$matches[2][$num]}{$matches[3][$num]}' target='_blank' title='".strip_tags($matches[4][$num])."'>{$matches[4][$num]}</a>",$text,1);
}
于 2012-01-23T22:30:09.153 回答