Php 自动向关键字字符串添加链接

Php 自动向关键字字符串添加链接,php,arrays,algorithm,Php,Arrays,Algorithm,在我的文章中,我想自动添加关键字的链接。 我的关键字数组: $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

在我的文章中,我想自动添加关键字的链接。 我的关键字数组:

 $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;
}
私有函数关键字\u替换(字符串$string,数组$key\u数组)
{
$array\u first=$key\u数组;
$array_last=[];
foreach($array\u首先作为$key=>$value)
{
$array_last[$key]=[$key,$value['slug'],'';
}
$count=计数($array\u last);
对于($i=0;$i$i;$j--)
{
如果(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\u last;
foreach($key作为$key)
{
$string=str_ireplace($key[1],$key[0],$string);
}
foreach($key作为$key)
{
$string=str_ireplace($key[0],$key[2],$string);
}
返回$string;
}
结果:

 $str = "<p>Just a test: getName  testName";
 echo $this->keywords_replace($str,$keywords);
$str=“只是一个测试:getName testName”;
echo$this->keywords\u replace($str,$keywords);
就像这样:只是一个测试:

非常导入:如果字符串没有空格,它将不匹配。因为我将使用其他语言,句子将不会像英语那样有空格。喜欢Wordpress关键字自动链接


我认为我的代码并不完美,有没有更好的算法来实现这个功能?谢谢

首先,您需要使用存储在
$newKeywords
中的循环将数组的结构更改为key/value。然后使用
preg\u replace\u 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);
$newKeywords=[];
foreach($keywords作为$keyword)
$newKeywords[$keyword['slug']]=$keyword['url'];
$newStr=preg\u replace\u回调(“/(\w+/”),函数($m)use($newKeywords){
返回设置($newKeywords[$m[0]])?“”:$m[0];
}美元/平方米);
输出:

<p>Just a test: <a href='https://www.getname.com'>getName</a>  <a href='https://www.testname.com'>testName</a></p>
<p>Just a test: https://www.getname.com https://www.testname.com
<p>Just a test: <a href="https://www.getname.com">getName</a> <a href="https://www.testname.com">testName</a>
<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>
只是一个测试:


首先,您需要使用存储在
$newKeywords
中的循环将数组的结构更改为key/value。然后使用
preg\u replace\u 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);
$newKeywords=[];
foreach($keywords作为$keyword)
$newKeywords[$keyword['slug']]=$keyword['url'];
$newStr=preg\u replace\u回调(“/(\w+/”),函数($m)use($newKeywords){
返回设置($newKeywords[$m[0]])?“”:$m[0];
}美元/平方米);
输出:

<p>Just a test: <a href='https://www.getname.com'>getName</a>  <a href='https://www.testname.com'>testName</a></p>
<p>Just a test: https://www.getname.com https://www.testname.com
<p>Just a test: <a href="https://www.getname.com">getName</a> <a href="https://www.testname.com">testName</a>
<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>
只是一个测试:

检查中的结果,您可以使用并用相应的
url
值替换字符串中出现的所有
slug
单词:

$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);

您可以使用并用相应的
url
值替换字符串中出现的所有
slug
单词:

$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);

我的答案与上面一样使用preg\u 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);

我的答案与上面一样使用preg\u 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);

这是我的答案:谢谢@Nick

$content = array_reduce($keywords , function ($c, $v) {
    return preg_replace('/(>[^<>]*?)(' . $v['slug'] . ')([^<>]*?<)/', '$1<a href="'. $v['url'] . '">$2</a>$3', $c);
}, $str);
$content=array\u reduce($keywords,function($c,$v){

返回preg_replace('/(>[^]*?)('.$v['slug'])([^]*?这是我的答案:谢谢@Nick

$content = array_reduce($keywords , function ($c, $v) {
    return preg_replace('/(>[^<>]*?)(' . $v['slug'] . ')([^<>]*?<)/', '$1<a href="'. $v['url'] . '">$2</a>$3', $c);
}, $str);
$content=array\u reduce($keywords,function($c,$v){


返回preg_replace('/(>[^]*?)('.$v['slug'])([^]*?显示预期的数组示例我在输出后添加了效果。你的段塞主要是camelCase,还是更确切地说你关心大小写不敏感?我不关心小写和camelCase大写。显示预期的数组示例我在输出后添加了效果。你的段塞主要是camelCase,还是更确切地说你关心大小写不敏感Victity?我不在乎小写和camelCase大写。关键字没有替换为url,改为@DomainRocker抱歉,我误解了你的问题。我想我现在得到了你想要的。如果字符串没有空格,它将不匹配。因为我将使用其他语言,句子将不会像英语那样有空格。@DomainRocker你可以从正则表达式中删除
\\b
,这将停止它寻找空格。请注意,如果您有unicode字符,您可能还需要对正则表达式使用
u
修饰符。如果您可以用其他示例文本编辑您的问题,我很乐意编辑我的答案以满足这些要求。@DomainRocker我添加了一个新的update和基于您的演示。它适用于您的示例数据。关键字没有替换为url,改为@DomainRocker抱歉,我误解了您的问题。我想我现在得到了您想要的。如果字符串没有空格,它将不匹配。因为我将使用其他语言,句子将不会像英语那样有空格。@DomainRocker您可以重新设置从正则表达式中移动
\\b
,这将停止它寻找空格。请注意,如果您有unicode字符,您可能还需要对正则表达式使用
u
修饰符。如果您可以用其他示例文本编辑您的问题,我很乐意编辑我的答案以满足这些要求。@DomainRocker我已添加了一个新的更新和基于您的演示。它适用于您的示例数据。非常感谢,我第一次看到preg_replace_回调函数。如果字符串没有空格,它将不匹配。因为我将使用其他语言,句子将不会像英语那样有空格。非常感谢,我第一次看到preg_replace_回调函数。如果字符串没有空格,它将不匹配将不匹配。因为我将使用其他语言,所以句子将不匹配