实现简单的敏感词验证以及file函数去空格

4007次阅读 263人点赞 作者: WuBin 发布时间: 2021-10-29 09:31:32
扫码到手机查看

实现简单的敏感词验证

最近做一个留言板项目,里面牵扯到了需要对提交的留言进行验证,这可是个麻烦的工程。首先想到了是不是可以借助第三方的平台,这里尝试了百度的文本校验。但是还要花钱,于是就自己实现了一个简单的匹配。可以用于一些小的项目。

function sensitive($list, $string){
  //违规词的个数
  $count = 0;
  //违规词
  $sensitiveWord = ''; 
  //替换后的内容
  $stringAfter = $string;
  //定义正则表达式
  $pattern = "/".implode("|",$list)."/i";
  //匹配到了结果
  if(preg_match_all($pattern, $string, $matches)){
    //匹配到的数组
    $patternList = $matches[0];
    $count = count($patternList);
    //敏感词数组转字符串
    $sensitiveWord = implode(',', $patternList);
    //把匹配到的数组进行合并,替换使用
    $replaceArray = array_combine($patternList,array_fill(0,count($patternList),'*'));
    //结果替换
    $stringAfter = strtr($string, $replaceArray);
  }
  $log = "原句为 [ {$string} ]<br/>";
  if($count==0){
    $log .= "暂未匹配到敏感词!";
  }else{
    $log .= "匹配到 [ {$count} ]个敏感词:[ {$sensitiveWord} ]<br/>".
      "替换后为:[ {$stringAfter} ]";
  }
  return $log;
}

注意:在具体的使用时候,可以进行修改,然后封装进一个类中。《三》中提供封装的类。

//要过滤的内容 
$string = 'likeyou爱液喜欢小黑暴淫爱着的大黄'; 
//定义敏感词数组 从文件中获取
$list = file('色情词库.txt', FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
// $list_读取后的形式 = ['爱液', '爱女人', '暴淫'];
$result = sensitive($list, $string);
echo ($result);

最后得到的展示结果为:

原句为 [ likeyou爱液喜欢小黑暴淫爱着的大黄 ]
匹配到 [ 2 ]个敏感词:[ 爱液,暴淫 ]
替换后为:[ likeyou*喜欢小黑*爱着的大黄 ]

关于file函数的一个坑

当我在测试的时候,使用file将txt文件中的每一行存为一个数组项,然后再拼接成正则:

// txt文件中内容
内容1
内容2
...如此结构排列N行
$list = file('xx.txt');
$pattern = "/".implode("|",$list)."/i";
/*
打印$pattern得到的结果: 内容1 |内容2 |内容3/i"
*/

可以发现结果在内容1(空格)|内容2(空格)| 在每个项之间多了个空格!这直接导致了正则匹配的失败。

最后经过研究发现,解决这个问题需要给file函数传第二个参数:

$list= file('色情词库.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );

或者只需要一个参数也行

$list = file('色情词库.txt', FILE_IGNORE_NEW_LINES);

这样得到的结果,拼接各个数组项后就没有空格了。最终结果是:

/内容1|内容2|内容3/i  正确的结果

将功能函数进行封装

<?php
// 脏词过滤类
class DirtywordFilter
{
    private static $instance;
    // 存储脏词的数组
    private static $dirtys = [];
    // 存储敏感词的各种txt文件的文件夹
    const TXT_PATH = __DIR__ . '/txts/';

    public static function getInstance()
    {
        // 判断当前类是否为空,为空则new本身
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }
        self::$instance->getWordsToArray();
        //  保证每次通过getInstance方法拿到的句柄是同一个句柄
        return self::$instance;
    }

    // 加载禁词文件
    private function getWordsToArray()
    {
        $dh = opendir(self::TXT_PATH);
        while ($file = readdir($dh)) {
            if ($file != '.' && $file != '..') {
                // 读取的时候获取的每一项去掉空格
                self::$dirtys[] = file(self::TXT_PATH . $file, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
            }
        }
        closedir($dh);
    }

    // 过滤方法
    public function filter($str)
    {
        $result = [
            'success' => true,
            'count' => 0,
            'log' => '未查出敏感词'
        ];
        foreach (self::$dirtys as $key => $dirty) {
            $res = self::sensitive($dirty, $str);
            // 如果违禁词大于0 马上终止循环
            if ($res['count'] > 0) {
                $msg = "第{$key}轮查询结果,";
                $result['success'] = false;
                $result['count'] = $res['count'];
                $result['log'] = $msg . $res['log'];
                break;
            }
        }
        return $result;
    }

    /**
     * @todo 敏感词过滤,返回结果
     * @param array $list  定义敏感词一维数组
     * @param string $string 要过滤的内容
     * @return string $log 处理结果
     */
    private static function sensitive($list, $string)
    {
        //违规词的个数
        $count = 0;
        //违规词
        $sensitiveWord = '';
        //替换后的内容
        $stringAfter = $string;
        //定义正则表达式
        $pattern = "/".implode("|",$list)."/i";

        if(preg_match_all($pattern, $string, $matches)){ //匹配到了结果
            $patternList = $matches[0];  //匹配到的数组
            $count = count($patternList);
            $sensitiveWord = implode(',', $patternList); //敏感词数组转字符串
            $replaceArray = array_combine($patternList,array_fill(0,count($patternList),'*')); //把匹配到的数组进行合并,替换使用
            $stringAfter = strtr($string, $replaceArray); //结果替换
        }
        $log = "原句为 [ {$string} ]<br/>";
        if($count == 0) {
            $log .= "暂未匹配到敏感词!";
        }else{
            $log .= "匹配到 [ {$count} ]个敏感词:[ {$sensitiveWord} ]<br/>".
                "替换后为:[ {$stringAfter} ]";
        }
        return [
            'count' => $count,
            'log' => $log
        ];
    }

    private function __construct()
    {}
    private function __clone()
    {}
}
// 首先要引入
$dirty = DirtywordFilter::getInstance();
$res = $dirty->filter('各种敏感词');
if($res['success]) {
  echo '验证成功';
} else {
  echo '验证失败';
}

服务器空间有限,个人存了一些词库(txt版本的),如果有需要的同学可以邮箱联系我,我会在收到的第一时间给您发送。

如果大家有免费的内容审核平台接口使用,欢迎推荐~~

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:正则,敏感词审核
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    9603次阅读 623人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    4297次阅读 317人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    14452次阅读 948人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    13497次阅读 491人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    12015次阅读 963人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    16376次阅读 1307人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    15187次阅读 1234人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    29853次阅读 2347人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    25920次阅读 1995人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录