PHP-查找帖子中的所有超链接,添加target和rel=nofollow属性
我需要找到一种方法来阅读用户发布的内容,找到可能包含的任何超链接,创建锚定标记,向所有这些链接添加target和rel=nofollow属性 我遇到过一些类似以下的正则表达式解决方案:PHP-查找帖子中的所有超链接,添加target和rel=nofollow属性,php,hyperlink,attributes,nofollow,Php,Hyperlink,Attributes,Nofollow,我需要找到一种方法来阅读用户发布的内容,找到可能包含的任何超链接,创建锚定标记,向所有这些链接添加target和rel=nofollow属性 我遇到过一些类似以下的正则表达式解决方案: (?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\
(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))
<?php
function replaceLinks($text)
{
$regex = '/'
. '(?<!\S)'
. '(((ftp|https?)?:?)\/\/|www\.)'
. '(\S+?)'
. '(?=$|\s|[,]|\.\W|\.$)'
. '/m';
return preg_replace_callback($regex, function($match)
{
return '<a'
. ' target=""'
. ' rel="nofollow"'
. ' href="' . $match[0] . '">'
. $match[0]
. '</a>';
}, $text);
}
(2)以下两种(以下简称:::[a-z[a-z[[a-z[[[w-[w-[[w-[[[w-[[[w-[[w-[[[w-[[a-a-z[[a-z[[a-a-z[a-z[[[[w-[w-[[[[w-[[[[[C-z0-z0-9-10-10-10-9-10-9-9%[9-9-9-9%[9%[9%]]]]))))))))))))以下以下以下两个(以下以下以下两个::::::::::)以下以下以下以下以下((((())))))的((((())))))在(以下以下两个((((()))))两个(以下以下以下以下以下以下)两个((((()))){};:“,«»””))
但是在关于同一问题的其他问题上,强烈建议不要使用REGEX而使用PHP的DOMDocument
无论是哪种最好的方式,我都需要添加上面提到的一些属性,以便强化网站上的所有外部链接。您可能会感兴趣
您可以定义自己的过滤器等。使用jquery获取要发布的内容,并在发布到PHP之前对其进行处理
$('#idof_content').val(
$('#idof_content').val().replace(/\b(http(s|):\/\/|)(www\.\S+)/ig,
"<a href='http\$2://\$3' target='_blank' rel='nofollow'>\$3</a>"));
$('idof#u content').val(
$(“#idof_content').val()。替换(/\b(http(s):\/\/\/\)(www\.\s+/ig,
""));
首先,您提到的指导原则建议不要使用正则表达式解析HTML。据我所知,您试图做的是解析用户的纯文本,并将其转换为HTML。为此,正则表达式通常很好
(请注意,我假设您自己将文本解析为链接,而不是使用外部库。在后一种情况下,您需要修复库输出的HTML,为此,您应该使用DOMDocument
迭代所有
标记并添加它们适当的属性。)
现在,您可以用两种方式解析它:服务器端或客户端
服务器端
优点:
- 它输出即用HTML
- 它不需要用户启用Javascript
- 您需要添加
属性,使机器人程序不跟随链接rel=“nofollow”
- 您不需要为机器人添加
属性,因为它们首先看不到链接——它们是用Javascript生成的,机器人通常不会解析Javascriptrel=“nofollow”
- 以这种方式创建链接需要用户启用Javascript
- 在Javascript中实现这样的东西会给人一种网站速度慢的印象,特别是当有很多文本需要解析时
- 这使得缓存解析的文本变得困难
(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))
<?php
function replaceLinks($text)
{
$regex = '/'
. '(?<!\S)'
. '(((ftp|https?)?:?)\/\/|www\.)'
. '(\S+?)'
. '(?=$|\s|[,]|\.\W|\.$)'
. '/m';
return preg_replace_callback($regex, function($match)
{
return '<a'
. ' target=""'
. ' rel="nofollow"'
. ' href="' . $match[0] . '">'
. $match[0]
. '</a>';
}, $text);
}
每个测试用例由两部分组成:源输入和预期输出。我使用以下代码确定函数是否通过上述测试:
foreach ($tests as $test)
{
list ($source, $expected) = $test;
$actual = replaceLinks($source);
if ($actual != $expected)
{
echo 'Test ' . $source . ' failed.' . PHP_EOL;
echo 'Expected: ' . $expected . PHP_EOL;
echo 'Actual: ' . $actual . PHP_EOL;
die;
}
}
echo 'All tests passed' . PHP_EOL;
我想这会让你知道如何解决这个问题。请随意添加更多的测试,并对regex本身进行实验,以使其适合你的特定需要。这将如何将请求的属性排除到我的网站的内部链接中?我能问一下,这是否会提取所有类型的链接,http或https、www或非www