在php中自动将关键字转换为链接

在php中自动将关键字转换为链接,php,regex,Php,Regex,我试图将文本中存储在数组中的特定关键字转换为链接 示例文本: $text='This text contains many keywords, but also formated <a href="#keywords" title="keywords">keywords</a>.' 我对正则表达式不太在行,但也许这一个可以: /[^#>"]keywords/i $string = 'This text contains many keywords, but al

我试图将文本中存储在数组中的特定关键字转换为链接

示例文本:

$text='This text contains many keywords, but also formated <a href="#keywords" title="keywords">keywords</a>.'

我对正则表达式不太在行,但也许这一个可以:

/[^#>"]keywords/i
$string = 'This text contains many keywords, but also formated <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>.';
$string = preg_replace("/(?<![#>\".\/])keywords/i", "<a href=\"http://www.keywords.com/keywords\" title=\"keywords\">$0</a>", $string);
echo $string;

// outputs: This text contains many <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>, but also formated <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>.
我认为它将忽略
#关键字
>关键字
关键字
的任何实例,然后查找其余的


编辑

经过测试,它似乎也替换了单词前的空格,如果字符串的开头是
关键字,它就不起作用。它也没有保留原始大小写。我已经测试过这个,它对我来说非常有效:

$string = "Keywords and keywords, plus some more keywords with the original <a href=\"#keywords\" title=\"keywords\">keywords</a>.";
$string = preg_replace("/(?<![#>\"])keywords/i", "<a href=\"#keywords\">$0</a>", $string);
echo $string;
$string=“关键字和关键字,再加上一些原始关键字。”;
$string=preg\u replace(“/(?\”])关键字/i“,”,$string);
echo$字符串;
前三个被替换,保留原始资本,最后一个保持不变。这个使用and


编辑2:

OP编辑的问题。在提供的新示例中,以下正则表达式将起作用:

/[^#>"]keywords/i
$string = 'This text contains many keywords, but also formated <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>.';
$string = preg_replace("/(?<![#>\".\/])keywords/i", "<a href=\"http://www.keywords.com/keywords\" title=\"keywords\">$0</a>", $string);
echo $string;

// outputs: This text contains many <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>, but also formated <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>.
$string='此文本包含许多关键字,但也已格式化';
$string=preg\u replace(“/(?\”\/])关键字/i“,”,$string);
echo$字符串;
//输出:此文本包含许多,但也已格式化。

这将替换前面没有
,或

关键字的所有实例。我对正则表达式不太在行,但这一个可能会起作用:

/[^#>"]keywords/i
$string = 'This text contains many keywords, but also formated <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>.';
$string = preg_replace("/(?<![#>\".\/])keywords/i", "<a href=\"http://www.keywords.com/keywords\" title=\"keywords\">$0</a>", $string);
echo $string;

// outputs: This text contains many <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>, but also formated <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>.
我认为它将忽略
#关键字
>关键字
关键字
的任何实例,然后查找其余的


编辑

经过测试,它似乎也替换了单词前的空格,如果字符串的开头是
关键字,它就不起作用。它也没有保留原始大小写。我已经测试过这个,它对我来说非常有效:

$string = "Keywords and keywords, plus some more keywords with the original <a href=\"#keywords\" title=\"keywords\">keywords</a>.";
$string = preg_replace("/(?<![#>\"])keywords/i", "<a href=\"#keywords\">$0</a>", $string);
echo $string;
$string=“关键字和关键字,再加上一些原始关键字。”;
$string=preg\u replace(“/(?\”])关键字/i“,”,$string);
echo$字符串;
前三个被替换,保留原始资本,最后一个保持不变。这个使用and


编辑2:

OP编辑的问题。在提供的新示例中,以下正则表达式将起作用:

/[^#>"]keywords/i
$string = 'This text contains many keywords, but also formated <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>.';
$string = preg_replace("/(?<![#>\".\/])keywords/i", "<a href=\"http://www.keywords.com/keywords\" title=\"keywords\">$0</a>", $string);
echo $string;

// outputs: This text contains many <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>, but also formated <a href="http://www.keywords.com/keywords" title="keywords">keywords</a>.
$string='此文本包含许多关键字,但也已格式化';
$string=preg\u replace(“/(?\”\/])关键字/i“,”,$string);
echo$字符串;
//输出:此文本包含许多,但也已格式化。

这将替换前面没有前面有

的所有
关键字实例。您可以更改正则表达式,使其只针对前面有空格的关键字。因为格式化的关键字不包含空格。这里有一个例子

$text = preg_replace('/ keywords/i',' <a href="#keywords">keywords</a>',$text);
$text=preg_replace('/keywords/i',''$text);

您可以更改正则表达式,使其只针对前面有空格的关键字。因为格式化的关键字不包含空格。这里有一个例子

$text = preg_replace('/ keywords/i',' <a href="#keywords">keywords</a>',$text);
$text=preg_replace('/keywords/i',''$text);
问题出在这里:

关键字可以在href、标题或链接文本中,也可以在其中的任何位置(例如,如果关键字是
sanity
,并且您已经有
href=“insanity”
。或者更糟糕的是,您可能有一个非关键字链接,其中恰好包含关键字,例如:

<a href="http://example.org/">Click here to find more keywords and such!</a>
但是你不能这样做,因为在这个例子中,lookback有一个通配符。没有它,你会得到一个超级贪婪的表达式

因此,我建议的替代方法是使用正则表达式查找所有链接元素,然后用占位符替换它们,最后用占位符替换它们

我是这样做的:

$text='This text contains many keywords, but also formated <a href="#keywords" title="keywords">keywords</a>.';
$keywords = array('text', 'formatted', 'keywords');

//This is just to make the regex easier
$keyword_list_pattern = '['. implode($keywords,"|") .']';

// First, get all matching keywords that are inside link elements
preg_match_all('/<a.*' . $keyword_list_pattern . '.*<\/a>/', $text, $links);
$links = array_unique($links[0]);  // Cleaning up array for next step.

// Second, swap out all matches with a placeholder, and build restore array:
foreach($links as $count => $link) {
     $link_key = "xxx_{$count}_xxx";
     $restore_links[$link_key] = $link;
     $text = str_replace($link, $link_key, $text);
}

// Third, we build a nice replacement array for the keywords:

foreach($keywords as $keyword) {
        $keyword_links[$keyword] = "<a href='#$keyword'>$keyword</a>";
}

// Merge the restore links to the bottom of the keyword links for one mass replacement:

$keyword_links = array_merge($keyword_links, $restore_links);

$text = str_replace(array_keys($keyword_links), $keyword_links, $text);

echo $text;
$text=”此文本包含许多关键字,但也已格式化。“;
$keywords=数组('text','formatted','keywords');
//这只是为了简化正则表达式
$keywords_list_pattern='['。内爆($keywords,“|”)。];
//首先,获取链接元素中的所有匹配关键字
preg_match_all(“/”;
}
//将还原链接合并到关键字链接的底部,以进行一次批量替换:
$keyword\u links=array\u merge($keyword\u links,$restore\u links);
$text=str_replace(数组_键($keyword_链接),$keyword_链接,$text);
echo$文本;
问题出在这里:

关键字可以在href、标题或链接文本中,也可以在其中的任何位置(例如,如果关键字是
sanity
,并且您已经有
href=“insanity”
。或者更糟糕的是,您可能有一个非关键字链接,其中恰好包含关键字,例如:

<a href="http://example.org/">Click here to find more keywords and such!</a>
但是你不能这样做,因为在这个例子中,lookback有一个通配符。没有它,你会得到一个超级贪婪的表达式

因此,我建议的替代方法是使用正则表达式查找所有链接元素,然后用占位符替换它们,最后用占位符替换它们

我是这样做的:

$text='This text contains many keywords, but also formated <a href="#keywords" title="keywords">keywords</a>.';
$keywords = array('text', 'formatted', 'keywords');

//This is just to make the regex easier
$keyword_list_pattern = '['. implode($keywords,"|") .']';

// First, get all matching keywords that are inside link elements
preg_match_all('/<a.*' . $keyword_list_pattern . '.*<\/a>/', $text, $links);
$links = array_unique($links[0]);  // Cleaning up array for next step.

// Second, swap out all matches with a placeholder, and build restore array:
foreach($links as $count => $link) {
     $link_key = "xxx_{$count}_xxx";
     $restore_links[$link_key] = $link;
     $text = str_replace($link, $link_key, $text);
}

// Third, we build a nice replacement array for the keywords:

foreach($keywords as $keyword) {
        $keyword_links[$keyword] = "<a href='#$keyword'>$keyword</a>";
}

// Merge the restore links to the bottom of the keyword links for one mass replacement:

$keyword_links = array_merge($keyword_links, $restore_links);

$text = str_replace(array_keys($keyword_links), $keyword_links, $text);

echo $text;
$text=”此文本包含许多关键字,但也已格式化。“;
$keywords=数组('text','formatted','keywords');
//这只是为了简化正则表达式
$keywords_list_pattern='['。内爆($keywords,“|”)。];
//首先,获取链接元素中的所有匹配关键字
preg_match_all(“/”;
}
//将还原链接合并到关键字链接的底部,以进行一次批量替换:
$keyword\u links=array\u merge($keyword\u links,$restore\u links);
$text=str_replace(数组_键($keyword_链接),$keyword_链接,$text);
echo$文本;

只有我的2美分,但由于href的“#something”实际上是一个有效的引用,我建议使用其他的东西,例如百分号,这样你就不会在某一天看到它了