ps:09年网上掀起了敏感字词过滤热,一时想到就动手干起来了,此算法借鉴经典的WM算法改写而成,不足之处还需优化和改进,测试时只对屏蔽的illegal keywords 进行了个数统计!
有需要测试用的,请在最后自己下载这两个肮脏的文件,请勿在JE上到处传播,大家都是文明人哈!
1.MutiPatternParser.java
package com.mutiplepatternmatch;
import java.util.Vector;
/**
*
* @author Daniel
*
*/
public class MutiPatternParser {
public MutiPatternParser() {
}
private boolean initFlag = false;
private UnionPatternSet unionPatternSet = new UnionPatternSet();
private int maxIndex = (int) java.lang.Math.pow(2, 16);
private int shiftTable[] = new int[maxIndex];
public Vector<AtomicPattern> hashTable[] = new Vector[maxIndex];
private UnionPatternSet tmpUnionPatternSet = new UnionPatternSet();
public boolean addFilterKeyWord(String keyWord, int level) {
if (initFlag == true)
return false;
UnionPattern unionPattern = new UnionPattern();
String []strArray = keyWord.split(" ");
for (int i = 0; i < strArray.length; i++) {
Pattern pattern = new Pattern(strArray[i]);
AtomicPattern atomicPattern = new AtomicPattern(pattern);
unionPattern.addNewAtomicPattrn(atomicPattern);
unionPattern.setLevel(level);
atomicPattern.setBelongUnionPattern(unionPattern);
}
tmpUnionPatternSet.addNewUnionPattrn(unionPattern);
return true;
}
private boolean isValidChar(char ch) {
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')
|| (ch >= 'a' && ch <= 'z'))
return true;
if ((ch >= 0x4e00 && ch <= 0x7fff) || (ch >= 0x8000 && ch <= 0x952f))
return true;//简体中文汉字编码
return false;
}
public String parse(String content, Vector<Integer> levelSet) {
if (initFlag == false)
init();
Vector<AtomicPattern> aps = new Vector<AtomicPattern>();
String preContent = preConvert(content);
for (int i = 0; i < preContent.length();) {
char checkChar = preContent.charAt(i);
if (shiftTable[checkChar] == 0) {
Vector<AtomicPattern> tmpAps = new Vector<AtomicPattern>();
tmpAps = findMathAps(preContent.substring(0, i + 1),
hashTable[checkChar]);
aps.addAll(tmpAps);
i++;
} else
i = i + shiftTable[checkChar];
}
parseAtomicPatternSet(aps, levelSet);
return content;
}
private void parseAtomicPatternSet(Vector<AtomicPattern> aps,
Vector<Integer> levelSet) {
while (aps.size() > 0) {
AtomicPattern ap = aps.get(0);
UnionPattern up = ap.belongUnionPattern;
if (up.isIncludeAllAp(aps) == true) {
levelSet.add(new Integer(up.getLevel()));
}
aps.remove(0);
}
}
private Vector<AtomicPattern> findMathAps(String src,
Vector<AtomicPattern> destAps) {
Vector<AtomicPattern> aps = new Vector<AtomicPattern>();
for (int i = 0; i < destAps.size(); i++) {
AtomicPattern ap = destAps.get(i);
if (ap.findMatchInString(src) == true)
aps.add(ap);
}
return aps;
}
private String preConvert(String content) {
String retStr = new String();
for (int i = 0; i < content.length(); i++) {
char ch = content.charAt(i);
if (this.isValidChar(ch) == true) {
retStr = retStr + ch;
}
}
return retStr;
}
// shift table and hash table of initialize
private void init() {
initFlag = true;
for (int i = 0; i < maxIndex; i++)
hashTable[i] = new Vector<AtomicPattern>();
shiftTableInit();
hashTableInit();
}
public void clear() {
tmpUnionPatternSet.clear();
initFlag = false;
}
private void shiftTableInit() {
for (int i = 0; i < maxIndex; i++)
shiftTable[i] = 2;
Vector<UnionPattern> upSet = tmpUnionPatternSet.getSet();
for (int i = 0; i < upSet.size(); i++) {
Vector<AtomicPattern> apSet = upSet.get(i).getSet();
for (int j = 0; j < apSet.size(); j++) {
AtomicPattern ap = apSet.get(j);
Pattern pattern = ap.getPattern();
if (shiftTable[pattern.charAtEnd(1)] != 0)
shiftTable[pattern.charAtEnd(1)] = 1;
if (shiftTable[pattern.charAtEnd(0)] != 0)
shiftTable[pattern.charAtEnd(0)] = 0;
}
}
}
private void hashTableInit() {
Vector<UnionPattern> upSet = tmpUnionPatternSet.getSet();
for (int i = 0; i < upSet.size(); i++) {
Vector<AtomicPattern> apSet = upSet.get(i).getSet();
for (int j = 0; j < apSet.size(); j++) {
AtomicPattern ap = apSet.get(j);
Pattern pattern = ap.getPattern();
if (pattern.charAtEnd(0) != 0) {
hashTable[pattern.charAtEnd(0)].add(ap);
}
}
}
}
}
class Pattern { // string
Pattern(String str) {
this.str = str;
}
public char charAtEnd(int index) {
if (str.length() > index) {
return str.charAt(str.length() - index - 1);
} else
return 0;
}
public String str;
public String getStr() {
return str;
};
}
class AtomicPattern {
public boolean findMatchInString(String str) {
if (this.pattern.str.length() > str.length())
return false;
int beginIndex = str.length() - this.pattern.str.length();
String eqaulLengthStr = str.substring(beginIndex);
if (this.pattern.str.equalsIgnoreCase(eqaulLengthStr))
return true;
return false;
}
AtomicPattern(Pattern pattern) {
this.pattern = pattern;
};
private Pattern pattern;
public UnionPattern belongUnionPattern;
public UnionPattern getBelongUnionPattern() {
return belongUnionPattern;
}
public void setBelongUnionPattern(UnionPattern belongUnionPattern) {
this.belongUnionPattern = belongUnionPattern;
}
public Pattern getPattern() {
return pattern;
}
public void setPattern(Pattern pattern) {
this.pattern = pattern;
}
}
class SameAtomicPatternSet {
SameAtomicPatternSet() {
SAPS = new Vector<AtomicPattern>();
};
public Vector<AtomicPattern> SAPS;
}
class UnionPattern { // union string
UnionPattern() {
this.apSet = new Vector<AtomicPattern>();
}
public Vector<AtomicPattern> apSet;
public void addNewAtomicPattrn(AtomicPattern ap) {
this.apSet.add(ap);
}
public Vector<AtomicPattern> getSet() {
return apSet;
}
public boolean isIncludeAllAp(Vector<AtomicPattern> inAps) {
if (apSet.size() > inAps.size())
return false;
for (int i = 0; i < apSet.size(); i++) {
AtomicPattern ap = apSet.get(i);
if (isInAps(ap, inAps) == false)
return false;
}
return true;
}
private boolean isInAps(AtomicPattern ap, Vector<AtomicPattern> inAps) {
for (int i = 0; i < inAps.size(); i++) {
AtomicPattern destAp = inAps.get(i);
if (ap.getPattern().str.equalsIgnoreCase(destAp.getPattern().str) == true)
return true;
}
return false;
}
public void setLevel(int level) {
this.level = level;
}
public int getLevel() {
return this.level;
}
private int level;
}
class UnionPatternSet { // union string set
UnionPatternSet() {
this.unionPatternSet = new Vector<UnionPattern>();
}
public void addNewUnionPattrn(UnionPattern up) {
this.unionPatternSet.add(up);
}
public Vector<UnionPattern> unionPatternSet;
public Vector<UnionPattern> getSet() {
return unionPatternSet;
}
public void clear() {
unionPatternSet.clear();
}
}
2.TxtReader.java
package com.mutiplepatternmatch;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
/**
*
* @author Daniel
*
*/
public class TxtReader implements Serializable{
public TxtReader() {
super();
}
public static BufferedReader keywordReader(String fileName){
File file=new File(fileName);
BufferedReader br=null;
try {
FileInputStream in=new FileInputStream(file);
InputStreamReader inReader = new InputStreamReader(in, "UTF-8");
br=new BufferedReader(inReader);
} catch (FileNotFoundException e) {
System.out.println("你想加载的文件没有找到!!!");
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
System.out.println("你指定的编码类型不支持哦!!!");
e.printStackTrace();
}
return br;
}
}
3.FilterTest.java
package com.mutiplepatternmatch;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Vector;
public class FilterTest {
public static void main(String args[]) {
MutiPatternParser filterEngine = new MutiPatternParser();
BufferedReader brKeyword = TxtReader
.keywordReader("file/illegalkeyword.txt");
BufferedReader brArticle = TxtReader.keywordReader("file/article.txt");
String keyword = null;
String article = null;
long startTime=System.currentTimeMillis();
StringBuffer buffer=new StringBuffer();
Vector<Integer> levelSet = new Vector<Integer>();
try {
while ((keyword = brKeyword.readLine()) != null) {
filterEngine.addFilterKeyWord(keyword, 1);
}
while ((article = brArticle.readLine()) != null) {
buffer.append(article);
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("读取文件IO异常!!!");
e.printStackTrace();
}
String content=filterEngine.parse(buffer.toString(), levelSet);
System.out.println("article.txt test:levelSet.size="
+ levelSet.size()+"\n this article's content: "+content);
long endTime=System.currentTimeMillis();
System.out.println("Cost:"+(endTime-startTime)+"ms");
/* 清除过滤算法引擎,带来的后果是引擎中将找不到任何的字符,测试代码,用来重载关键字时使用! */
filterEngine.clear();
levelSet.clear();
filterEngine.parse("我我我 你你你 他他他", levelSet);
System.out.println("test:levelSet.size=" + levelSet.size());// 测试正确结果是找不到匹配字符
levelSet.clear();
filterEngine.parse("a'b'c a b c", levelSet);
System.out.println("test:tz levelSet.size=" + levelSet.size());// 测试正确结果是找不到匹配字符*/
}
}
- file.rar (9.2 KB)
- 描述: 过滤关键字文件,提供测试用!请勿流氓
- 下载次数: 655
分享到:
相关推荐
本文将详细探讨这些知识点,并结合“关键字过滤多模式匹配算法(支持中文)”这一主题,深入解析相关技术和应用。 首先,关键字过滤是一种技术,用于从大量文本数据中筛选出包含特定关键字或短语的信息。这种技术...
关键字过滤算法 本文档描述的是一个关于关键字过滤的算法,该算法不同于其他过滤算法的是,它是...该关键字过滤算法可以快速匹配关键字,且可以处理中英文混合文本。该算法的时间复杂度较低,可以满足实际应用的需求。
网站关键字过滤技术的核心在于如何有效地匹配和处理这些关键字。一种常见的方法是使用正则表达式,它可以灵活地匹配各种模式,包括完整的词汇、部分词汇甚至是特定的字符组合。另一种常见的方式是使用字典匹配,将...
2. **字符串操作**:关键字过滤的关键在于对输入字符串的处理。这涉及到字符串的查找、替换和判断等操作,例如使用`indexOf()`或`contains()`方法检查关键字是否存在,使用`replace()`或`replaceAll()`方法替换非法...
关键字过滤可能包括但不限于删除、替换或标记含有特定关键字的字符串部分。 1. **关键字列表**:这是过滤器的核心,可以是一个静态的字符串数组,也可以是动态加载的配置文件。开发者可以根据业务需求定义哪些词汇...
文本中的关键字匹配是信息检索和自然语言处理领域中的一个核心问题。...在提供的压缩包文件`9c14e1d84ba14c5d877e2b73ed8c4542`中,可能包含了具体的关键字匹配算法实现代码或示例,可以进一步学习和研究。
多模式匹配算法是一种在文本中查找多个模式(关键词)的技术,广泛应用于文本过滤、搜索引擎、生物信息学等领域。AC算法,全称为Aho-Corasick算法,是解决此类问题的一种高效方法,尤其在处理大量模式时表现优秀。该...
对于正则表达式匹配,这是一种强大的文本处理工具,可以灵活定义模式来查找和替换特定的字符串。关键词库比对则是将待检查的文本与预设的非法关键字列表进行比较,如果存在匹配项,则进行过滤。自然语言处理则更进阶...
字符串模糊匹配在很多场景都有应用,例如: - 访问控制列表(ACL)的实现,如例子中的准入授权配置。 - 文件系统搜索,根据部分路径或文件名进行查找。 - 用户输入的命令行解析,支持通配符。 - 日志分析,根据...
这些算法可以是简单的字符串匹配,如全词匹配或部分匹配,也可以是更复杂的模糊匹配或模式匹配,用于识别变形或组合的关键字。 3. **实时监测**: 为了实时防止关键字的出现,网站通常会设置实时监控系统。一旦...
wm c算法实现。WM算法采用字符块技术,增大了主串和模式串不匹配的可能性.从而增加了直接跳跃的机会:它...在现有的多关键字匹配算法中,使用块字符、Hash技术和前缀特征表技术的WM算法通常被认为具有最高的效率。.rar
多模匹配算法是一种在文本搜索和处理中广泛使用的高效技术,尤其在互联网环境中,大量数据的快速检索至关重要。Aho-Corasick算法是多模匹配算法的一种,由Aho和Corasick在1975年提出,它利用有限自动机的概念实现了...
wm c算法实现。WM算法采用字符块技术,增大了主串和模式串不匹配的可能性.从而增加了直接跳跃的机会:它...在现有的多关键字匹配算法中,使用块字符、Hash技术和前缀特征表技术的WM算法通常被认为具有最高的效率。.zip
wm c算法实现。WM算法采用字符块技术,增大了主串和模式串不匹配的可能性.从而增加了直接跳跃的机会:它...在现有的多关键字匹配算法中,使用块字符、Hash技术和前缀特征表技术的WM算法通常被认为具有最高的效率。.zip
- **多字符串匹配算法**:如AC自动机(Aho-Corasick Automaton)。 本案例中使用了正则表达式来进行关键字匹配,这是一种较为简单且易于实现的方法。 #### 三、Java敏感词过滤实现详解 根据提供的代码片段,我们...
它们可以帮助开发者检查字符串的开头或结尾是否符合特定模式,例如验证文件路径、URL等是否以特定字符或字符串开头或结束。 4. `AnsiReplaceText` 函数:此函数用于在原始字符串(AText)中替换所有出现的指定子串...