Sco*_*t B 10 php regex preg-match
以下函数旨在将rel="nofollow"属性应用于所有外部链接,而不是内部链接,除非该路径与$my_folder下面定义的预定义根URL匹配.
所以考虑到变量......
$my_folder = 'http://localhost/mytest/go/';
$blog_url = 'http://localhost/mytest';
Run Code Online (Sandbox Code Playgroud)
而内容......
<a href="http://localhost/mytest/">internal</a>
<a href="http://localhost/mytest/go/hostgator">internal cloaked link</a>
<a href="http://cnn.com">external</a>
Run Code Online (Sandbox Code Playgroud)
最终结果,更换后应该......
<a href="http://localhost/mytest/">internal</a>
<a href="http://localhost/mytest/go/hostgator" rel="nofollow">internal cloaked link</a>
<a href="http://cnn.com" rel="nofollow">external</a>
Run Code Online (Sandbox Code Playgroud)
请注意,第一个链接不会更改,因为它是一个内部链接.
第二行上的链接也是一个内部链接,但由于它匹配我们的$my_folder字符串,它nofollow也会得到.
第三个链接是最简单的,因为它与它不匹配blog_url,它显然是一个外部链接.
但是,在下面的脚本中,我的所有链接都已获得nofollow.如何修复脚本以执行我想要的操作?
function save_rseo_nofollow($content) {
$my_folder = $rseo['nofollow_folder'];
$blog_url = get_bloginfo('url');
preg_match_all('~<a.*>~isU',$content["post_content"],$matches);
for ( $i = 0; $i <= sizeof($matches[0]); $i++){
if ( !preg_match( '~nofollow~is',$matches[0][$i])
&& (preg_match('~' . $my_folder . '~', $matches[0][$i])
|| !preg_match( '~'.$blog_url.'~',$matches[0][$i]))){
$result = trim($matches[0][$i],">");
$result .= ' rel="nofollow">';
$content["post_content"] = str_replace($matches[0][$i], $result, $content["post_content"]);
}
}
return $content;
}
Run Code Online (Sandbox Code Playgroud)
ale*_*lex 14
这是DOMDocument解决方案......
$str = '<a href="http://localhost/mytest/">internal</a>
<a href="http://localhost/mytest/go/hostgator">internal cloaked link</a>
<a href="http://cnn.com" rel="me">external</a>
<a href="http://google.com">external</a>
<a href="http://example.com" rel="nofollow">external</a>
<a href="http://stackoverflow.com" rel="junk in the rel">external</a>
';
$dom = new DOMDocument();
$dom->preserveWhitespace = FALSE;
$dom->loadHTML($str);
$a = $dom->getElementsByTagName('a');
$host = strtok($_SERVER['HTTP_HOST'], ':');
foreach($a as $anchor) {
$href = $anchor->attributes->getNamedItem('href')->nodeValue;
if (preg_match('/^https?:\/\/' . preg_quote($host, '/') . '/', $href)) {
continue;
}
$noFollowRel = 'nofollow';
$oldRelAtt = $anchor->attributes->getNamedItem('rel');
if ($oldRelAtt == NULL) {
$newRel = $noFollowRel;
} else {
$oldRel = $oldRelAtt->nodeValue;
$oldRel = explode(' ', $oldRel);
if (in_array($noFollowRel, $oldRel)) {
continue;
}
$oldRel[] = $noFollowRel;
$newRel = implode($oldRel, ' ');
}
$newRelAtt = $dom->createAttribute('rel');
$noFollowNode = $dom->createTextNode($newRel);
$newRelAtt->appendChild($noFollowNode);
$anchor->appendChild($newRelAtt);
}
var_dump($dom->saveHTML());
Run Code Online (Sandbox Code Playgroud)
string(509) "<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<a href="http://localhost/mytest/">internal</a>
<a href="http://localhost/mytest/go/hostgator">internal cloaked link</a>
<a href="http://cnn.com" rel="me nofollow">external</a>
<a href="http://google.com" rel="nofollow">external</a>
<a href="http://example.com" rel="nofollow">external</a>
<a href="http://stackoverflow.com" rel="junk in the rel nofollow">external</a>
</body></html>
"
Run Code Online (Sandbox Code Playgroud)
首先尝试使其更具可读性,然后才能使if规则更复杂:
function save_rseo_nofollow($content) {
$content["post_content"] =
preg_replace_callback('~<(a\s[^>]+)>~isU', "cb2", $content["post_content"]);
return $content;
}
function cb2($match) {
list($original, $tag) = $match; // regex match groups
$my_folder = "/hostgator"; // re-add quirky config here
$blog_url = "http://localhost/";
if (strpos($tag, "nofollow")) {
return $original;
}
elseif (strpos($tag, $blog_url) && (!$my_folder || !strpos($tag, $my_folder))) {
return $original;
}
else {
return "<$tag rel='nofollow'>";
}
}
Run Code Online (Sandbox Code Playgroud)
给出以下输出:
[post_content] =>
<a href="http://localhost/mytest/">internal</a>
<a href="http://localhost/mytest/go/hostgator" rel=nofollow>internal cloaked link</a>
<a href="http://cnn.com" rel=nofollow>external</a>
Run Code Online (Sandbox Code Playgroud)
原始代码中的问题可能是$ rseo,它没有在任何地方声明.
试试这个(PHP 5.3+):
和代码:
function nofollow($html, $skip = null) {
return preg_replace_callback(
"#(<a[^>]+?)>#is", function ($mach) use ($skip) {
return (
!($skip && strpos($mach[1], $skip) !== false) &&
strpos($mach[1], 'rel=') === false
) ? $mach[1] . ' rel="nofollow">' : $mach[0];
},
$html
);
}
Run Code Online (Sandbox Code Playgroud)
例子:
echo nofollow('<a href="link somewhere" rel="something">something</a>');
// will be same because it's already contains rel parameter
echo nofollow('<a href="http://www.cnn.com">something</a>'); // ad
// add rel="nofollow" parameter to anchor
echo nofollow('<a href="http://localhost">something</a>', 'localhost');
// skip this link as internall link
Run Code Online (Sandbox Code Playgroud)