基于PHP实现敏感词过滤功能
作者:小柳666
后端同学在做一些社区论坛类型项目时候,可能会绕不开敏感词的过滤这个功能,特别是在微信小程序中,如果主营类目被定义为【社交】 那么敏感词、图片、视频的各种过滤功能是逃不掉的,否则是无法上线的,下面就以PHP代码为例,分析一下这个功能的具体实现
需求分析
既然是敏感词过滤,那么肯定是需要有一张敏感词的数据表的。
大概就是上面这个样子。
思路一
刚拿到需求我的第一实现思路就是,当获取到用户提交的评论内容以后,把数据库中的每一个屏蔽词都用正则去匹配一下。如果匹配到数据,那么就把匹配到的问题替换成 ** ,最后就把原文跟匹配完成的文字进行存储即可。大体的代码可能是下面这个样子。
$str = '我爱中国,我是卖qiang的,请与我联系'; $pattern = '/卖qiang/i'; $replacement = '**'; echo preg_replace($pattern,$replacement,$str); // 输出 我爱中国,我是**的,请与我联系
上面的代码是正确的,但是假如屏蔽词的数量有几千条,那么每一个词都需要跟待匹配的文字匹配一遍,那就是几千次,程序的执行效率太差。
思路二 一次匹配多个词
既然一次匹配一个词效率太低,那可以尝试一次匹配多个词。大致修改的代码是下面这个样子。
$str = '我爱中国,我是卖qiang的,请与我联系'; $pattern = '/卖qiang|与我|非法|动物|系/i'; //这里会追加很多个词 $replacement = '**'; echo preg_replace($pattern,$replacement,$str); // 我爱中国,我是**的,请**联**
这样的话,几千个屏蔽词组成一个正则。匹配一次就可以完成字符串的替换。但是假如屏蔽词的数量有十万,那正则的这个变量肯定超出内存报错了。这种情况下就需要分组进行处理数据了。
$str = '我爱中国,我是卖qiang的,请与我联系'; $block_arr = ['1','2','3',...,'100000']; $sm_list = array_chunk($block_list, 1000); foreach ($sm_list as $key => $value) { $pattern = "/" . implode("|", array_column($list, 'word')) . "/i"; //这里会追加很多个词 $replacement = '**'; $str = preg_replace($pattern,$replacement,$str); } echo $str; // 我爱中国,我是**的,请**联**
上面的代码中,我们将一个无比巨大的数组,以1000为单位进行拆分。然后批量的去替换掉目标数据中可能存在的敏感词。这样就完成了敏感词的过滤功能。
优化选项
- 敏感词是一次查询,数据量多的情况下每次都会很耗费资源。所以我们是需要把查询出来的敏感词放到redis缓存之中的。
- 敏感词匹配中,要先匹配长的,然后采取匹配短的。sql语句的排序 ->orderRaw('LENGTH(word) desc')
到此这篇关于基于PHP实现敏感词过滤功能的文章就介绍到这了,更多相关PHP敏感词过滤内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!