在我的文章中,我想自动向关键字添加链接。 我的关键字数组:
$keywords = [
0=>['id'=>1,'slug'=>'getName','url'=>'https://example.com/1'],
1=>['id'=>2,'slug'=>'testName','url'=>'https://example.com/2'],
2=>['id'=>3,'slug'=>'ign','url'=>'https://example.com/3'],
];
这是我的代码:
private function keywords_replace(string $string, array $key_array)
{
$array_first = $key_array;
$array_last = [];
foreach ($array_first as $key=>$value)
{
$array_last[$key] = [$key, $value['slug'], '<a target="_blank" href="' . $value['url'] . '" title="' . $value['slug'] . '">' . $value['slug'] . '</a>'];
}
$count = count($array_last);
for ($i=0; $i<$count;$i++)
{
for ($j=$count-1;$j>$i;$j--)
{
if (strlen($array_last[$j][1]) > strlen($array_last[$j-1][1]))
{
$tmp = $array_last[$j];
$array_last[$j] = $array_last[$j-1];
$array_last[$j-1] = $tmp;
}
}
}
$keys = $array_last;
foreach ($keys as $key)
{
$string = str_ireplace($key[1],$key[0],$string);
}
foreach ($keys as $key)
{
$string = str_ireplace($key[0],$key[2],$string);
}
return $string;
}
结果:
$str = "<p>Just a test: getName testName";
echo $this->keywords_replace($str,$keywords);
像这样:只需测试:getName testName
非常导入:如果字符串中没有空格,则不会匹配。由于我将使用其他语言,因此句子中将不会包含英语等空格。像Wordpress关键字自动链接一样
我认为我的代码并不完美,是否有更好的算法来实现此功能?谢谢!
答案 0 :(得分:1)
首先,您需要使用将结果存储在$newKeywords
中的循环将数组的结构更改为键/值。然后使用preg_replace_callback()
选择字符串中的每个单词,并检查它是否存在于数组键中。如果存在,请将其包装在锚定标记中。
$newKeywords = [];
foreach ($keywords as $keyword)
$newKeywords[$keyword['slug']] = $keyword['url'];
$newStr = preg_replace_callback("/(\w+)/", function($m) use($newKeywords){
return isset($newKeywords[$m[0]]) ? "<a href='{$newKeywords[$m[0]]}'>{$m[0]}</a>" : $m[0];
}, $str);
输出:
<p>Just a test: <a href='https://www.getname.com'>getName</a> <a href='https://www.testname.com'>testName</a></p>
在demo中查看结果
答案 1 :(得分:1)
您可以使用array_reduce
和preg_replace
用相应的slug
值替换字符串中所有出现的url
字:
$keywords = [
0=>['id'=>1,'slug'=>'getName','url'=>'https://www.getname.com'],
1=>['id'=>2,'slug'=>'testName','url'=>'https://www.testname.com'],
2=>['id'=>3,'slug'=>'ign','url'=>'https://www.ign.com'],
];
$str = "<p>Just a test: getName testName";
echo array_reduce($keywords, function ($c, $v) { return preg_replace('/\\b(' . $v['slug'] . ')\\b/', $v['url'], $c); }, $str);
输出:
<p>Just a test: https://www.getname.com https://www.testname.com
更新
要将文本更改为链接,您需要使用以下代码:
echo array_reduce($keywords,
function ($c, $v) {
return preg_replace('/\\b(' . $v['slug'] . ')\\b/',
'<a href="'. $v['url'] . '">$1</a>', $c);
},
$str);
输出:
<p>Just a test: <a href="https://www.getname.com">getName</a> <a href="https://www.testname.com">testName</a>
更新2
由于某些被替换的链接包含的单词也是slug
的值,因此有必要使用strtr
的数组格式立即进行所有替换。我们使用array_column
,array_combine
和array_map
构建一系列模式和替换,然后将其传递给strtr
:
$reps = array_combine(array_column($keywords, 'slug'),
array_map(function ($k) { return '<a href="' . $k['url'] .'">' . $k['slug'] . '</a>'; }, $keywords
));
$newstr = strtr($str, $reps);
答案 2 :(得分:1)
我的答案与上述Nick's一样使用preg_replace。
它依赖于模式和替换大小相等的数组,以及相应的模式和替换。
需要尊重单词边界,我怀疑您可以通过简单的字符串替换来做到这一点。
<?php
$keywords = [
0=>['id'=>1,'slug'=>'foo','url'=>'https://www.example.com/foo'],
1=>['id'=>2,'slug'=>'bar','url'=>'https://www.example.com/bar'],
2=>['id'=>3,'slug'=>'baz','url'=>'https://www.example.com/baz'],
];
foreach ($keywords as $item)
{
$patterns[] = '@\b(' . $item['slug'] . ')\b@i';
$replacements[] = '<a href="' . $item['url'] . '">$1</a>';
}
$html = "<p>I once knew a barbed man named <i>Foo</i>, he often visited the bar.</p>";
print preg_replace($patterns, $replacements, $html);
输出:
<p>I once knew a barbed man named <i><a href="https://www.example.com/foo">Foo</a></i>, he often visited the <a href="https://www.example.com/bar">bar</a>.</p>
答案 3 :(得分:0)
这是我的答案:感谢@Nick
$content = array_reduce($keywords , function ($c, $v) {
return preg_replace('/(>[^<>]*?)(' . $v['slug'] . ')([^<>]*?<)/', '$1<a href="'. $v['url'] . '">$2</a>$3', $c);
}, $str);