如何实现敏感词词库过滤?

目前有个需求是对文章内容进行敏感词标注并过滤,敏感词词库如果不多的话,可以用一个循环来处理,但是实际使用当中,词库的数据量可能有几万个词

对于词库数量上完个,而且过滤结果需要标记的,有没有什么第三方库或者其他设计思路推荐?

最终效果就是输入待检测文本,输出命中的关键词词组,并对原文命中词语进行其他颜色的标注!

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 23
chowjiawei

坐等 高性能回答

2年前 评论

可以了解下 AC 自动机的算法

2年前 评论
2年前 评论
clark (楼主) 2年前
oOops 2年前
win27149 (作者) 2年前

可以使用HTMLPurifier来过滤

2年前 评论

es 检索,高亮?

2年前 评论
Tangqy 2年前
wuchenge

用第三方,我用的百度

2年前 评论
clark (楼主) 2年前
  1. 调用第三方审核接口 比如百度
  2. dfa算法 可以自己写 网上也有很多现成的
2年前 评论
Mumujin

简单粗暴的设计思路。

  • 是对敏感词分类(文件方式)
  • 检测用户输入对某类型的敏感词输入(后期对用户行为进行评估)

use SplFileObject;
use Symfony\Component\Finder\Finder;
use Illuminate\Support\LazyCollection;
use Symfony\Component\Finder\SplFileInfo;
use Illuminate\Contracts\Filesystem\FileNotFoundException;

class Sensitive
{
    protected array $items = [];

    public function __construct(string $dir)
    {
        $this->items = collect($this->findFilesByExt($dir, '.txt'))
            ->map(fn($file) => $this->lines($file));
    }

    public function filter($content)
    {
        return $this->items->map(
            fn($lazy) => $lazy->map(
                fn($line) => $line !== '' && str_contains($content, $line)
            )->filter()->all()
        )->filter();
    }

    public function findFilesByExt(string $path, string $ext = '.php'): array
    {
        $files = [];

        $path = realpath($path);

        foreach (Finder::create()->files()->name('*'. $ext)->in($path) as $file) {
            $directory = $this->nestedDirectory($file, $path);
            $files[$directory.basename($file->getRealPath(), $ext)] = $file->getRealPath();
        }

        ksort($files, SORT_NATURAL);

        return $files;
    }

    public function nestedDirectory(SplFileInfo $file, string $path)
    {
        $directory = $file->getPath();

        if ($nested = trim(str_replace($path, '', $directory), DIRECTORY_SEPARATOR)) {
            $nested = str_replace(DIRECTORY_SEPARATOR, '.', $nested).'.';
        }

        return $nested;
    }

    // 引用 laravel filesystem code.
    public function lines($path)
    {
        if (! is_file($path)) {
            throw new FileNotFoundException(
                "File does not exist at path {$path}."
            );
        }

        return LazyCollection::make(function () use ($path) {
            $file = new SplFileObject($path);

            $file->setFlags(SplFileObject::DROP_NEW_LINE);

            while (! $file->eof()) {
                yield $file->fgets();
            }
        });
    }
}
2年前 评论

是输入文本的预检测吗?这样的话不适合频繁用后端,可以放前端检测,有类似的js。服务端检测可以试试 scws 中文分词自定义词库。感觉几万条不很多,只要不是循环处理的应该效率问题不大。

2年前 评论
mouyong

来来来,刚好最近做了一个包 packagist.org/packages/mouyong/sen...

api 正在开发中。

file

2年前 评论
mouyong (作者) 2年前

github.com/larvatecn/laravel-censo... 拿去不谢,支持腾讯云,百度云,本地词库

2年前 评论

你也可以试试这个,能满足你需求。

github.com/Sy-Dante/laravel-sensit...

该包允许在任何地方使用,不依赖任何框架,如 Laravel 框架。

需要自己定义敏感词,也支持你从数据库等其他地方获取敏感词并 动态设置

可以使用 filter 方法直接过滤敏感词,替换成你指定的文本,如 *。也可以使用 search 方法查出文本包含哪些敏感词后,也就是你说的 关键词词组,然后通过使用 php 函数 str_replace 批量替换,增加 <b> 之类标签自定义高亮。
而且包还支持排除干扰因子,如:你-是-s-a,如果你设置了 - 是干扰因子,sa 是敏感词的话,就能找出 s-a 触发了敏感词。

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!