@@ -233,10 +240,18 @@ public class SensitiveWordBs { context.wordData(wordData); context.wordTag(wordTag); context.charIgnore(charIgnore); + context.wordResultCondition(wordResultCondition); return context; } + public SensitiveWordBs wordResultCondition(IWordResultCondition wordResultCondition) { + ArgUtil.notNull(wordResultCondition, "wordResultCondition"); + + this.wordResultCondition = wordResultCondition; + return this; + } + public SensitiveWordBs charIgnore(ISensitiveWordCharIgnore charIgnore) { ArgUtil.notNull(charIgnore, "charIgnore"); diff --git a/src/main/java/com/github/houbb/sensitive/word/bs/SensitiveWordContext.java b/src/main/java/com/github/houbb/sensitive/word/bs/SensitiveWordContext.java index 6167b5e..5598f76 100644 --- a/src/main/java/com/github/houbb/sensitive/word/bs/SensitiveWordContext.java +++ b/src/main/java/com/github/houbb/sensitive/word/bs/SensitiveWordContext.java @@ -113,6 +113,13 @@ public class SensitiveWordContext implements IWordContext { */ private ISensitiveWordCharIgnore charIgnore; + /** + * 敏感词结果匹配 + * + * @since 0.13.0 + */ + private IWordResultCondition wordResultCondition; + public IWordData wordData() { return wordData; } @@ -304,4 +311,13 @@ public class SensitiveWordContext implements IWordContext { this.charIgnore = charIgnore; return this; } + + public IWordResultCondition wordResultCondition() { + return wordResultCondition; + } + + public SensitiveWordContext wordResultCondition(IWordResultCondition wordResultCondition) { + this.wordResultCondition = wordResultCondition; + return this; + } } diff --git a/src/main/java/com/github/houbb/sensitive/word/core/SensitiveWord.java b/src/main/java/com/github/houbb/sensitive/word/core/SensitiveWord.java index 338ffdb..479bc50 100644 --- a/src/main/java/com/github/houbb/sensitive/word/core/SensitiveWord.java +++ b/src/main/java/com/github/houbb/sensitive/word/core/SensitiveWord.java @@ -1,10 +1,7 @@ package com.github.houbb.sensitive.word.core; import com.github.houbb.heaven.util.guava.Guavas; -import com.github.houbb.sensitive.word.api.IWordCheck; -import com.github.houbb.sensitive.word.api.ISensitiveWord; -import com.github.houbb.sensitive.word.api.IWordContext; -import com.github.houbb.sensitive.word.api.IWordResult; +import com.github.houbb.sensitive.word.api.*; import com.github.houbb.sensitive.word.api.context.InnerSensitiveWordContext; import com.github.houbb.sensitive.word.constant.enums.WordValidModeEnum; import com.github.houbb.sensitive.word.support.check.WordCheckResult; @@ -59,6 +56,7 @@ public class SensitiveWord extends AbstractSensitiveWord { .wordContext(context) .modeEnum(WordValidModeEnum.FAIL_OVER) .formatCharMapping(characterCharacterMap); + final IWordResultCondition wordResultCondition = context.wordResultCondition(); for (int i = 0; i < text.length(); i++) { WordCheckResult checkResult = sensitiveCheck.sensitiveCheck(i, checkContext); @@ -70,7 +68,10 @@ public class SensitiveWord extends AbstractSensitiveWord { WordResult wordResult = WordResult.newInstance() .startIndex(i) .endIndex(i+wordLength); - resultList.add(wordResult); + //v0.13.0 添加判断 + if(wordResultCondition.match(wordResult, text, modeEnum, context)) { + resultList.add(wordResult); + } // 快速返回 if (WordValidModeEnum.FAIL_FAST.equals(modeEnum)) { diff --git a/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/AbstractWordResultCondition.java b/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/AbstractWordResultCondition.java new file mode 100644 index 0000000..53b5a6f --- /dev/null +++ b/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/AbstractWordResultCondition.java @@ -0,0 +1,22 @@ +package com.github.houbb.sensitive.word.support.resultcondition; + +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; + +/** + * 抽象实现 + * + * @since 0.13.0 + */ +public abstract class AbstractWordResultCondition implements IWordResultCondition { + + protected abstract boolean doMatch(IWordResult wordResult, String text, WordValidModeEnum modeEnum, IWordContext context); + + @Override + public boolean match(IWordResult wordResult, String text, WordValidModeEnum modeEnum, IWordContext context) { + return doMatch(wordResult, text, modeEnum, context); + } + +} diff --git a/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/WordResultConditionAlwaysTrue.java b/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/WordResultConditionAlwaysTrue.java new file mode 100644 index 0000000..f667e89 --- /dev/null +++ b/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/WordResultConditionAlwaysTrue.java @@ -0,0 +1,19 @@ +package com.github.houbb.sensitive.word.support.resultcondition; + +import com.github.houbb.sensitive.word.api.IWordContext; +import com.github.houbb.sensitive.word.api.IWordResult; +import com.github.houbb.sensitive.word.constant.enums.WordValidModeEnum; + +/** + * 恒为真 + * + * @since 0.13.0 + */ +public class WordResultConditionAlwaysTrue extends AbstractWordResultCondition { + + @Override + protected boolean doMatch(IWordResult wordResult, String text, WordValidModeEnum modeEnum, IWordContext context) { + return true; + } + +} diff --git a/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/WordResultConditionEnglishWordMatch.java b/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/WordResultConditionEnglishWordMatch.java new file mode 100644 index 0000000..0e0df1d --- /dev/null +++ b/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/WordResultConditionEnglishWordMatch.java @@ -0,0 +1,50 @@ +package com.github.houbb.sensitive.word.support.resultcondition; + +import com.github.houbb.heaven.util.lang.CharUtil; +import com.github.houbb.heaven.util.util.CharsetUtil; +import com.github.houbb.sensitive.word.api.IWordContext; +import com.github.houbb.sensitive.word.api.IWordResult; +import com.github.houbb.sensitive.word.constant.enums.WordValidModeEnum; + +/** + * 英文单词必须要全词匹配 + * + * https://github.com/houbb/sensitive-word/issues/45 + * + * @since 0.13.0 + */ +public class WordResultConditionEnglishWordMatch extends AbstractWordResultCondition { + + @Override + protected boolean doMatch(IWordResult wordResult, String text, WordValidModeEnum modeEnum, IWordContext context) { + final int startIndex = wordResult.startIndex(); + final int endIndex = wordResult.endIndex(); + // 判断当前是否为英文单词 + for(int i = startIndex; i < endIndex; i++) { + char c = text.charAt(i); + if(!CharUtil.isEnglish(c)) { + return true; + } + } + + // 判断处理,判断前一个字符是否为英文。如果是,则不满足 + if(startIndex > 0) { + char preC = text.charAt(startIndex-1); + if(CharUtil.isEnglish(preC)) { + return false; + } + } + + // 判断后一个字符是否为英文 + if(endIndex < text.length() - 1) { + char afterC = text.charAt(endIndex+1); + if(CharUtil.isEnglish(afterC)) { + return false; + } + } + + return true; + } + + +} diff --git a/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/WordResultConditions.java b/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/WordResultConditions.java new file mode 100644 index 0000000..21d86eb --- /dev/null +++ b/src/main/java/com/github/houbb/sensitive/word/support/resultcondition/WordResultConditions.java @@ -0,0 +1,29 @@ +package com.github.houbb.sensitive.word.support.resultcondition; + +import com.github.houbb.sensitive.word.api.IWordResultCondition; + +/** + * 匹配结果工具类 + * + * @since 0.13.0 + */ +public final class WordResultConditions { + + /** + * 恒为真 + * @return 结果 + */ + public static IWordResultCondition alwaysTrue() { + return new WordResultConditionAlwaysTrue(); + } + + /** + * 如果是英文,则必须全词匹匹配 + * @return 结果 + * @since 0.13.0 + */ + public static IWordResultCondition englishWordMatch() { + return new WordResultConditionEnglishWordMatch(); + } + +} diff --git a/src/test/java/com/github/houbb/sensitive/word/bs/SensitiveWordBsConfigTest.java b/src/test/java/com/github/houbb/sensitive/word/bs/SensitiveWordBsConfigTest.java index 0252501..131f189 100644 --- a/src/test/java/com/github/houbb/sensitive/word/bs/SensitiveWordBsConfigTest.java +++ b/src/test/java/com/github/houbb/sensitive/word/bs/SensitiveWordBsConfigTest.java @@ -3,6 +3,7 @@ package com.github.houbb.sensitive.word.bs; import com.github.houbb.sensitive.word.support.allow.WordAllows; import com.github.houbb.sensitive.word.support.deny.WordDenys; import com.github.houbb.sensitive.word.support.ignore.SensitiveWordCharIgnores; +import com.github.houbb.sensitive.word.support.resultcondition.WordResultConditions; import com.github.houbb.sensitive.word.support.tag.WordTags; import org.junit.Assert; import org.junit.Test; @@ -31,6 +32,7 @@ public class SensitiveWordBsConfigTest { .numCheckLen(8) .wordTag(WordTags.none()) .charIgnore(SensitiveWordCharIgnores.defaults()) + .wordResultCondition(WordResultConditions.alwaysTrue()) .init(); final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。"; diff --git a/src/test/java/com/github/houbb/sensitive/word/bs/SensitiveWordBsResultConditionTest.java b/src/test/java/com/github/houbb/sensitive/word/bs/SensitiveWordBsResultConditionTest.java new file mode 100644 index 0000000..f5d69a0 --- /dev/null +++ b/src/test/java/com/github/houbb/sensitive/word/bs/SensitiveWordBsResultConditionTest.java @@ -0,0 +1,106 @@ +package com.github.houbb.sensitive.word.bs; + +import com.github.houbb.sensitive.word.api.IWordDeny; +import com.github.houbb.sensitive.word.support.resultcondition.WordResultConditions; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + *
project: sensitive-word-SensitiveWordBsTest
+ *create on 2020/1/7 23:43
+ * + * @author Administrator + * @since 0.13.0 + */ +public class SensitiveWordBsResultConditionTest { + + @Test + public void alwaysTrueTest() { + final String text = "I have a nice day。"; + + List