zoukankan      html  css  js  c++  java
  • php过滤敏感词库算法

    本人网上搜集的敏感词库

    https://gitee.com/likxarlit/file_php.git

    <?php
    /**
     * Created by PhpStorm.
     * User: Administrator
     * Date: 2021/11/11
     * Time: 10:39
     */
    
    class filterWords
    {
        protected $dict;//敏感词字典
    
        public function __construct($arr)
        {
            $this->loadDataFormFile($arr);
        }
    
        /**
         * 从文件中加载敏感词字典
         */
        protected function loadDataFormFile($arr)
        {
            //此处可以修改为读文件,一般敏感词为文件形式,一行对应一个敏感词
            //如果经常调用的话,还可以通过缓存处理(redis、memcache)等等,此处不详细处理
            //将敏感词加入此次节点
            foreach ($arr as $value) {
                $this->addWords(trim($value));
            }
        }
        /**
         * 分割文本
         * @param $str
         * @return array[]|false|string[]
         */
        protected function splitStr($str)
        {
            //将字符串分割成组成它的字符
            // 其中/u 表示按unicode(utf-8)匹配(主要针对多字节比如汉字),否则默认按照ascii码容易出现乱码
            return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
        }
    
        /**
         * 添加敏感字至节点
         * @param $words
         */
        protected function addWords($words)
        {
            //1.分割字典
            $wordArr = $this->splitStr($words);
            $curNode = &$this->dict;
            foreach ($wordArr as $char) {
                if (!isset($curNode)) {
                    $curNode[$char] = [];
                }
                $curNode = &$curNode[$char];
            }
            //标记到达当前节点完整路径为"敏感词"
            $curNode['end']++;
        }
    
        /**
         * 敏感词校验
         * @param $str ;需要校验的字符串
         * @param int $level ;屏蔽词校验等级 1-只要顺序包含都屏蔽;2-中间间隔skipDistance个字符就屏蔽;3-全词匹配即屏蔽
         * @param int $skipDistance ;允许敏感词跳过的最大距离,如笨aa蛋a傻瓜等等
         * @param bool $isReplace ;是否需要替换,不需要的话,返回是否有敏感词,否则返回被替换的字符串
         * @param string $replace ;替换字符
         * @return bool|string
         */
        public function filter($str, $level = 1, $skipDistance = 2, $isReplace = true, $replace = '*')
        {
            //允许跳过的最大距离
            if ($level == 1) {
                $maxDistance = strlen($str) + 1;
            } elseif ($level == 2) {
                $maxDistance = max($skipDistance, 0) + 1;
            } else {
                $maxDistance = 2;
            }
            $strArr = $this->splitStr($str);
            $strLength = count($strArr);
            $isSensitive = false;
            for ($i = 0; $i < $strLength; $i++) {
                //判断当前敏感字是否有存在对应节点
                $curChar = $strArr[$i];
                if (!isset($this->dict[$curChar])) {
                    continue;
                }
                $isSensitive = true; //引用匹配到的敏感词节点
                $curNode = &$this->dict[$curChar];
                $dist = 0;
                $matchIndex = [$i]; //匹配后续字符串是否match剩余敏感词
                for ($j = $i + 1; $j < $strLength && $dist < $maxDistance; $j++) {
                    if (!isset($curNode[$strArr[$j]])) {
                        $dist++; continue;
                    }
                    //如果匹配到的话,则把对应的字符所在位置存储起来,便于后续敏感词替换
                    $matchIndex[] = $j;
                    //继续引用
                    $curNode = &$curNode[$strArr[$j]];
                }
                //判断是否已经到敏感词字典结尾,是的话,进行敏感词替换
                if (isset($curNode['end']) && $isReplace) {
                    foreach ($matchIndex as $index) {
                        $strArr[$index] = $replace;
                    }
                    $i = max($matchIndex);
                }
            }
            if ($isReplace) {
                return implode('', $strArr);
            } else {
                return $isSensitive;
            }
        }
    }
    

    使用

    require_once "../../model/filterWords.php";
    
    $str = '测试评论:艾迪在KTV出 111 售防卫刀具专卖';
    $data = json_decode(file_get_contents(Spider_PATH."../sensitive"),true);
    $filterWords = new filterWords($data);
    $str = $filterWords->filter($str,1);
    print_r($str);
    
  • 相关阅读:
    xxl-job如何保证调度的一致性
    mac安装homebrew
    JDBC自动加载驱动的SPI机制
    JDBC使用
    mysql的limit分页,越往后为什么越慢,怎么解决
    解决idea报错 "cannot access class
    BeanUtils.copyProperties复制失败探究
    xxl-job任务定时触发流程
    xxl-job一致性
    xxl-job高可用部署
  • 原文地址:https://www.cnblogs.com/ljkltt/p/15539669.html
Copyright © 2011-2022 走看看