release branch 0.23.0

This commit is contained in:
houbb
2024-12-08 21:42:59 +08:00
parent 4d606eaf08
commit d7f7c0aa0a
9 changed files with 321 additions and 9 deletions

View File

@@ -374,3 +374,9 @@
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|:---|:-----|----------|:--------------------|:------------------------------------------------------|
| 1 | F | 修正数字匹配问题 | 2024-11-10 22:43:08 | https://github.com/houbb/sensitive-word/issues/84 |
# release_0.23.0
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|:---|:-----|------------|:-------------------|:-----------|
| 1 | A | 进一步拓展结果条件类 | 2024-12-8 21:13:44 | 支持同时指定多个条件 |

View File

@@ -64,6 +64,10 @@
- 修正单个敏感词修改时,对应的格式处理问题
### V0.23.0
- 结果条件拓展支持 wordTags 和 chains
## 更多资料
### 敏感词控台
@@ -94,7 +98,7 @@
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>sensitive-word</artifactId>
<version>0.22.0</version>
<version>0.23.0</version>
</dependency>
```
@@ -656,11 +660,13 @@ public class SensitiveWordService {
WordResultConditions 工具类可以获取匹配策略
| 实现 | 说明 | 支持版本 |
|:----|:------------|:--------|
| alwaysTrue | 恒为真 | |
| englishWordMatch | 英文单词全词匹配 | v0.13.0 |
| englishWordNumMatch | 英文单词/数字全词匹配 | v0.20.0 |
| 实现 | 说明 | 支持版本 |
|:-------------------------------------------|:--------------------|:--------|
| alwaysTrue | 恒为真 | |
| englishWordMatch | 英文单词全词匹配 | v0.13.0 |
| englishWordNumMatch | 英文单词/数字全词匹配 | v0.20.0 |
| wordTags | 满足特定标签的,比如只关注【广告】标签 | v0.23.0 |
| chains(IWordResultCondition ...conditions) | 支持指定多个条件,同时满足 | v0.23.0 |
## 使用例子
@@ -702,6 +708,81 @@ Assert.assertEquals("[]", wordList.toString());
当然可以根据需要实现更加复杂的策略。
## wordTags 单词标签
支持版本: `v0.23.0`
我们可以只返回隶属于某一种标签的敏感词。
我们指定了两个敏感词商品、AV
MyWordTag 是我们定义的一个敏感词标签实现:
```java
/**
* 自定义单词标签
* @since 0.23.0
*/
public class MyWordTag extends AbstractWordTag {
private static Map<String, Set<String>> dataMap;
static {
dataMap = new HashMap<>();
dataMap.put("商品", buildSet("广告", "中文"));
dataMap.put("AV", buildSet("色情", "单词", "英文"));
}
private static Set<String> buildSet(String... tags) {
Set<String> set = new HashSet<>();
for(String tag : tags) {
set.add(tag);
}
return set;
}
@Override
protected Set<String> doGetTag(String word) {
return dataMap.get(word);
}
}
```
测试用例如下,我们模拟了两个不同的实现类,每一个关注的单词标签不同。
```java
// 只关心SE情
SensitiveWordBs sensitiveWordBsYellow = SensitiveWordBs.newInstance()
.wordDeny(new IWordDeny() {
@Override
public List<String> deny() {
return Arrays.asList("商品", "AV");
}
})
.wordAllow(WordAllows.empty())
.wordTag(new MyWordTag())
.wordResultCondition(WordResultConditions.wordTags(Arrays.asList("色情")))
.init();
// 只关心广告
SensitiveWordBs sensitiveWordBsAd = SensitiveWordBs.newInstance()
.wordDeny(new IWordDeny() {
@Override
public List<String> deny() {
return Arrays.asList("商品", "AV");
}
})
.wordAllow(WordAllows.empty())
.wordTag(new MyWordTag())
.wordResultCondition(WordResultConditions.wordTags(Arrays.asList("广告")))
.init();
final String text = "这些 AV 商品什么价格?";
Assert.assertEquals("[AV]", sensitiveWordBsYellow.findAll(text).toString());
Assert.assertEquals("[商品]", sensitiveWordBsAd.findAll(text).toString());
```
# 忽略字符
## 说明

View File

@@ -6,7 +6,7 @@
<groupId>com.github.houbb</groupId>
<artifactId>sensitive-word</artifactId>
<version>0.22.0</version>
<version>0.23.0</version>
<properties>
<!--============================== All Plugins START ==============================-->

View File

@@ -10,9 +10,9 @@ ECHO "============================= RELEASE START..."
:: 版本号信息(需要手动指定)
:::: 旧版本名称
SET version=0.22.0
SET version=0.23.0
:::: 新版本名称
SET newVersion=0.23.0
SET newVersion=0.24.0
:::: 组织名称
SET groupName=com.github.houbb
:::: 项目名称

View File

@@ -0,0 +1,43 @@
package com.github.houbb.sensitive.word.support.resultcondition;
import com.github.houbb.heaven.support.pipeline.Pipeline;
import com.github.houbb.heaven.support.pipeline.impl.DefaultPipeline;
import com.github.houbb.sensitive.word.api.IWordContext;
import com.github.houbb.sensitive.word.api.IWordResult;
import com.github.houbb.sensitive.word.api.IWordResultCondition;
import com.github.houbb.sensitive.word.constant.enums.WordValidModeEnum;
import java.util.List;
/**
* 结果条件的的初始化类
*
* @since 0.23.0
*/
public abstract class WordResultConditionInit extends AbstractWordResultCondition {
/**
* 初始化列表
*
* @param pipeline 当前列表泳道
* @since 0.0.13
*/
protected abstract void init(final Pipeline<IWordResultCondition> pipeline);
@Override
protected boolean doMatch(IWordResult wordResult, String text, WordValidModeEnum modeEnum, IWordContext context) {
Pipeline<IWordResultCondition> pipeline = new DefaultPipeline<>();
this.init(pipeline);
List<IWordResultCondition> conditionList = pipeline.list();
// 必须满足所有
for(IWordResultCondition wordResultCondition : conditionList) {
if(!wordResultCondition.match(wordResult, text, modeEnum, context)) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,52 @@
package com.github.houbb.sensitive.word.support.resultcondition;
import com.github.houbb.heaven.util.common.ArgUtil;
import com.github.houbb.heaven.util.util.CollectionUtil;
import com.github.houbb.sensitive.word.api.IWordContext;
import com.github.houbb.sensitive.word.api.IWordResult;
import com.github.houbb.sensitive.word.api.IWordTag;
import com.github.houbb.sensitive.word.constant.enums.WordValidModeEnum;
import java.util.Collection;
import java.util.Set;
/**
* 结果标签匹配的条件
*
* @since 0.23.0
*/
public class WordResultConditionWordTagsMatch extends AbstractWordResultCondition {
/**
* 指定标签的集合
*/
private final Collection<String> tags;
public WordResultConditionWordTagsMatch(Collection<String> tags) {
ArgUtil.notEmpty(tags, "tags");
this.tags = tags;
}
@Override
protected boolean doMatch(IWordResult wordResult, String text, WordValidModeEnum modeEnum, IWordContext context) {
// 判断对应的标签
String word = text.substring(wordResult.startIndex(), wordResult.endIndex());
final IWordTag wordTag = context.wordTag();
Set<String> wordTags = wordTag.getTag(word);
// 在指定的 tag 中
if(CollectionUtil.isEmpty(wordTags)) {
return false;
}
for(String tag : tags) {
if(wordTags.contains(tag)) {
return true;
}
}
return false;
}
}

View File

@@ -1,7 +1,12 @@
package com.github.houbb.sensitive.word.support.resultcondition;
import com.github.houbb.heaven.support.pipeline.Pipeline;
import com.github.houbb.heaven.util.common.ArgUtil;
import com.github.houbb.heaven.util.util.ArrayUtil;
import com.github.houbb.sensitive.word.api.IWordResultCondition;
import java.util.List;
/**
* 匹配结果工具类
*
@@ -35,4 +40,39 @@ public final class WordResultConditions {
return new WordResultConditionEnglishWordNumMatch();
}
/**
* 单词标签
* @param tags 标签列表
* @return 结果
* @since 0.23.0
*/
public static IWordResultCondition wordTags(List<String> tags) {
ArgUtil.notEmpty(tags, "tags");
return new WordResultConditionWordTagsMatch(tags);
}
/**
* 链式调用,支持同时满足多个条件
*
* @since 0.23.0
* @param condition 条件
* @param others 其他条件
* @return 结果
*/
public static IWordResultCondition chains(final IWordResultCondition condition, final IWordResultCondition ... others) {
return new WordResultConditionInit() {
@Override
protected void init(Pipeline<IWordResultCondition> pipeline) {
pipeline.addLast(condition);
if(ArrayUtil.isNotEmpty(others)) {
for(IWordResultCondition other : others) {
pipeline.addLast(other);
}
}
}
};
}
}

View File

@@ -0,0 +1,37 @@
package com.github.houbb.sensitive.word.support.resultcondition;
import com.github.houbb.sensitive.word.support.tag.AbstractWordTag;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* 自定义单词标签
* @since 0.23.0
*/
public class MyWordTag extends AbstractWordTag {
private static Map<String, Set<String>> dataMap;
static {
dataMap = new HashMap<>();
dataMap.put("商品", buildSet("广告", "中文"));
dataMap.put("AV", buildSet("色情", "单词", "英文"));
}
private static Set<String> buildSet(String... tags) {
Set<String> set = new HashSet<>();
for(String tag : tags) {
set.add(tag);
}
return set;
}
@Override
protected Set<String> doGetTag(String word) {
return dataMap.get(word);
}
}

View File

@@ -0,0 +1,53 @@
package com.github.houbb.sensitive.word.support.resultcondition;
import com.github.houbb.sensitive.word.api.IWordDeny;
import com.github.houbb.sensitive.word.bs.SensitiveWordBs;
import com.github.houbb.sensitive.word.support.allow.WordAllows;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class WordTagsTest {
/**
* 是否包含
*
* @since 0.23.0
*/
@Test
public void wordTagsTest() {
// 只关心SE情
SensitiveWordBs sensitiveWordBsYellow = SensitiveWordBs.newInstance()
.wordDeny(new IWordDeny() {
@Override
public List<String> deny() {
return Arrays.asList("商品", "AV");
}
})
.wordAllow(WordAllows.empty())
.wordTag(new MyWordTag())
.wordResultCondition(WordResultConditions.wordTags(Arrays.asList("色情")))
.init();
// 只关心广告
SensitiveWordBs sensitiveWordBsAd = SensitiveWordBs.newInstance()
.wordDeny(new IWordDeny() {
@Override
public List<String> deny() {
return Arrays.asList("商品", "AV");
}
})
.wordAllow(WordAllows.empty())
.wordTag(new MyWordTag())
.wordResultCondition(WordResultConditions.wordTags(Arrays.asList("广告")))
.init();
final String text = "这些 AV 商品什么价格?";
Assert.assertEquals("[AV]", sensitiveWordBsYellow.findAll(text).toString());
Assert.assertEquals("[商品]", sensitiveWordBsAd.findAll(text).toString());
}
}