文章内链关键词正则匹配应该怎么写

想要通过正则表达式实现文章关键词替换成链接的功能
我之前的写发是:

preg_replace("/(?<!['\"])".$keyword."(?!<\/a>)/",$replacement, $subject);

这样的方式可以实现关键词替换。
但是遇到了一个问题。
当$subject 被a标记包含 同时有其他词存在就会有冲突 例如:

$keyword = "关键词";
$subject = "<a href="www.example.com">这里是关键词的内容</a>"
$replacement = "<a href="target.com">管仅此</a>";
$result = preg_replace("/(?<!['\"])".$keyword."(?!<\/a>)/",$replacement, $subject);

这样的result结果就是有问题的 会在a标签内嵌套a标签。
想要的功能就是避免在a标签内嵌套。
请问如何写正确的正则表达式

阅读 3.1k
3 个回答

关键在于,先使 a标签 内容中的关键词消失,待处理完,再恢复。

$keyword = "关键词";
$id = "sz201907190550";
$subject = '<a href="www.example.com">这里是关键词的内容</a><p>关键词再出现</p><a href="#"><span>又一个关键词</span>出现</a>';
$replacement = '<a href="target.com">管仅此</a>';

// 1.将所有 a标签 内容中的关键词用一个原文中绝不可能出现的字符串替代
$subject = preg_replace("/(<a\s+.*?href=[\"\']?[^\"\' >]*[\"\']?[^>]*>.*?)".$keyword."(.*?<\/a>)/i", '${1}'.$id.'${2}', $subject);
// 2.题主原处理
$subject = preg_replace("/(?<!['\"])".$keyword."(?!<\/a>)/",$replacement, $subject);
// 3.恢复所有 a标签 内容中的关键词
$result = str_replace($id, $keyword, $subject);
echo $result

输出如下:

<a href="www.example.com">这里是关键词的内容</a><p><a href="target.com">管仅此</a>再出现</p><a href="#"><span>又一个关键词</span>出现</a>

先把目标字符串拆解成数组,然后循环数组是标签的跳过去,不是标签的再替换。
下面的是js,php应该也可以实现

str.match(/<[^>]+>|[^<|>|\w]+/mg).forEach(function(){ //todo:: })
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题