繁体   English   中英

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

[英]Automatically convert keywords to links in php

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

示例文字:

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

因此,现在我想将单词关键字转换为<a href="#keywords" title="keywords">#keywords</a>

我使用了非常简单的preg_replace函数

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

但显然它将转换为链接,也将已经格式化为链接的字符串转换为链接,因此我得到了一个凌乱的html,例如:

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

预期结果:

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

有什么建议么? 谢谢

编辑

我们距离完善的功能仅一步之遥,但在这种情况下仍然无法正常工作:

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

在这种情况下,它也替换了href中的word keywords ,因此我们再次得到了像这样的混乱代码

 <a href="http://www.<a href="http://www.keywords.com/keywords" title="keywords">keywords</a>.com/<a href="http://www.keywords.com/keywords" title="keywords">keywords</a>" title="keywords">keywords</a>

我对正则表达式不太满意,但也许这个可以用:

/[^#>"]keywords/i

我认为它将做的是忽略#keywords>keywords"keywords所有实例,并找到其余的实例。


编辑

经过测试后,它看起来也将替换单词之前的空格,并且如果keywords是字符串的开头,则该字符串将不起作用。 它还没有保留原始大写字母。 我已经测试了这一点,它对我来说非常合适:

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

前三个被替换,保留原始大小写,最后一个保持不变。 这使用负向后看反向引用


编辑2:

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

 $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>. 

这将替换的所有实例keywords不是由前面#>". ,或/

这是问题所在:

关键字可以在href,标题或链接文本中以及其中的任何位置(例如,关键字是sanity而您已经具有href="insanity" 。甚至更糟的是,您可能拥有非关键字)恰好包含关键字的链接,例如:

<a href="http://example.org/">Click here to find more keywords and such!</a>

在上面的示例中,即使它符合所有其他可能的条件(最容易测试的条件之前和之后都有空格),它仍然会导致链接中的链接,我认为这会中断互联网。

因此,您需要使用lookaheadslookbehinds来检查关键字是否包装在链接中。 但是有一个陷阱:后视必须具有定义的模式(意味着没有通配符)。

我以为自己会是英雄,并向您展示解决此问题的简便方法,因此可以达到以下目的:

'/(?<!\<a.?>)[list|of|keywords](?!\<\/a>)/'

除非您不能执行此操作,否则在本例中,后向具有该通配符。 没有它,您将最终获得超级贪婪的表情。

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

这是我的操作方式:

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

您可以更改RegEx,使其仅定位在前面有空格的关键字。 由于格式化的关键字不包含空格。 这是一个例子。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM