matlab敏感词输出代码,敏感词过滤的简易实现

介绍

很多时候我们需要对接受的文本进行过滤,剔除一下不当用词,比如一些反动的、侮辱性的、淫秽的用语

一般会有一个敏感词词库,基于这个词库对输入的文本进行过滤,分享一种简易的实现

示例中为了和谐,将不会出现上述违反社会主义核心价值观的词汇,使用“小明”、“小红”来举例

实际生产中可以用需要过滤的敏感词列表替换

现在假设“小明”、“小红”已经属于敏感词了,那么理想的效果:

输入: 小明上课吃零食,老师让小红出去。

输出: **上课吃零食,老师让**出去。

很多时候用户会简单的插入一些' '、'_'、'%'类似的简单字符来躲避过滤,希望算法同样能过滤敏感词:

输入: 小 明上课吃零食,老师让'小'红'出去

输出: * *上课吃零食,老师让'*'*'出去

准备

首先,需要准备一个敏感词列表

比如:

小明

小红

然后,需要一个高效的匹配算法

因为在实际生产中,敏感词数量会比较多,传入的文本也会比较长

单纯的遍历敏感词列表对字符串使用String.replace(key, "**")效果会比较差

这里使用了一种Aho Corasick自动机结合DoubleArrayTrie极速多模式匹配的算法来进行敏感词的匹配

实现

定义敏感词列表

private static final String[] SENSITIVE_KEYS = new String[]{

"小明",

"小红"

};

使用maven将算法库引用进来

com.hankcs

aho-corasick-double-array-trie

1.2.1

使用匹配器来匹配敏感词位置并替换为'*'

public static String shadowSensitive(String text) {

StringBuffer sb = new StringBuffer(text);

// filter sensitive words

List> hits = acdat.parseText(sb);

// shadow sensitive words

for (AhoCorasickDoubleArrayTrie.Hit hit : hits) {

for (int i = hit.begin; i < hit.end; i++ ){

sb.deleteCharAt(i);

sb.insert(i, "*");

}

}

return sb.toString();

}

接下来测试一下,需要先初始化一下匹配器

public static void main(String[] args) {

TreeMap keys = new TreeMap();

for (String key : SENSITIVE_KEYS) {

keys.put(key, key);

}

acdat = new AhoCorasickDoubleArrayTrie();

acdat.build(keys);

String text1 = "小明上课吃零食,老师让小红出去";

String text2 = "小 明上课吃零食,老师让'小'红'出去";

System.out.println("text1:");

System.out.println(text1);

System.out.println(shadowSensitive(text1));

System.out.println("text2:");

System.out.println(text2);

System.out.println(shadowSensitive(text2));

}

执行程序后,控制台输出

text1:

小明上课吃零食,老师让小红出去

**上课吃零食,老师让**出去

text2:

小 明上课吃零食,老师让'小'红'出去

小 明上课吃零食,老师让'小'红'出去

可以看到text1中“小明”和“小红”已经被替换成了“**”

但是,在词语中简单的加入一些字符就可以绕开过滤器,这还需要优化一下

优化

匹配器只能匹配到“小明”,而无法匹配到“小 明”或者“小_明”

优化的思路如下:

输入的文本

小 明上课吃零食,老师让'小'红'出去

将一些常见的字符取出来,只留下文字内容

小明上课吃零食,老师让小红出去

进行敏感词的匹配,将敏感词改为*

**上课吃零食,老师让**出去

将取出的字符再重新插回去

* *上课吃零食,老师让'*'*'出去

参照这个思路,改写了上面的shadowSensitive方法

改线前需要定义一些常见的字符

private static final char[] SPECIAL_CHARS = new char[]{

' ', '`', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '=','+',

'\\', '|', '[', '{', ']', '}', ';', ':', '\'', '"', ',', '', '/','?',

//中文字符

' ', '!', '¥', '…', '(', ')', '、', '「', '」', '【', '】', ';', ':', '“', '”', ',', '。', '《', '》', '?'};

为了方便展示,这里仅仅列举了常见的一部分字符,有需要的话,可以随时添加字符进去

优化的shadowSensitive方法:

public static String shadowSensitive(String text) {

// detect special chars

List descriptors = new ArrayList();

for (int i = 0; i < text.length(); i++) {

for (int j = 0; j < SPECIAL_CHARS.length; j++) {

if (text.charAt(i) == SPECIAL_CHARS[j]) {

int[] descriptor = new int[2];

descriptor[0] = i;

descriptor[1] = j;

descriptors.add(descriptor);

}

}

}

// remove special chars

StringBuffer sb = new StringBuffer(text);

for (int i = descriptors.size() - 1; i >= 0; i--) {

sb.deleteCharAt(descriptors.get(i)[0]);

}

// filter sensitive words

List> hits = acdat.parseText(sb);

// shadow sensitive words

for (AhoCorasickDoubleArrayTrie.Hit hit : hits) {

for (int i = hit.begin; i < hit.end; i++ ){

sb.deleteCharAt(i);

sb.insert(i, "*");

}

}

// refill special chars

for (int[] descriptor : descriptors) {

sb.insert(descriptor[0], SPECIAL_CHARS[descriptor[1]]);

}

return sb.toString();

}

接下来测试一下

public static void main(String[] args) {

TreeMap keys = new TreeMap();

for (String key : SENSITIVE_KEYS) {

keys.put(key, key);

}

acdat = new AhoCorasickDoubleArrayTrie();

acdat.build(keys);

String text1 = "小明上课吃零食,老师让小红出去";

String text2 = "小 明上课吃零食,老师让'小'红'出去";

System.out.println("text1:");

System.out.println(text1);

System.out.println(shadowSensitive(text1));

System.out.println("text2:");

System.out.println(text2);

System.out.println(shadowSensitive(text2));

}

执行程序后,控制台输出:

text1:

小明上课吃零食,老师让小红出去

**上课吃零食,老师让**出去

text2:

小 明上课吃零食,老师让'小'红'出去

* *上课吃零食,老师让'*'*'出去

可以看到"小 明"已经修改为""了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值