`

字符串多模式匹配算法:关键字过滤技术

阅读更多
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
分享到:
评论
3 楼 ftp51423121 2010-02-09  
这个很久之前就看到了~就是看不懂啊~~~~~~
2 楼 imjl 2010-01-06  
测试数据呢?
1 楼 wq13480 2010-01-06  
就是想要你的关键词呢.发出来吧!

相关推荐

    论文研究-多模式匹配快速算法的设计 .pdf

    多模式匹配快速算法的设计,李胜才,,字符串匹配速度是关键字检测和过滤系统的核心。本文在有限状态自动机的AC算法的基础上,综合BM算法的跳跃思想和QS算法的优点, 提��

    wm c算法实现。WM算法采用字符块技术,增大了主串和模式串不匹配的可能性

    wm c算法实现。WM算法采用字符块技术,增大了主串和模式串不匹配的可能性.从而增加了直接跳跃的机会:它...在现有的多关键字匹配算法中,使用块字符、Hash技术和前缀特征表技术的WM算法通常被认为具有最高的效率。.rar

    wm c算法实现 WM算法采用字符块技术,增大了主串和模式串不匹配的可能性.从而增加了直接跳跃的机会

    wm c算法实现。WM算法采用字符块技术,增大了主串和模式串不匹配的可能性.从而增加了直接跳跃的机会:它...在现有的多关键字匹配算法中,使用块字符、Hash技术和前缀特征表技术的WM算法通常被认为具有最高的效率。.zip

    wm c算法实现。WM算法采用字符块技术,增大了主串和模式串不匹配的可能性.从而增加了直接跳跃的机会

    wm c算法实现。WM算法采用字符块技术,增大了主串和模式串不匹配的可能性.从而增加了直接跳跃的机会:它...在现有的多关键字匹配算法中,使用块字符、Hash技术和前缀特征表技术的WM算法通常被认为具有最高的效率。.zip

    JavaScript经典实例

     1.1连接两个或多个字符串  1.2连接字符串和另一种数据类型  1.3条件比较字符串  1.4在字符串中查找子字符串  1.5从一个字符串提取子字符串  1.6检查一个存在的、非空的字符串  1.7将一个关键字字符串分解为...

    python cookbook(第3版)

    2.1 使用多个界定符分割字符串 2.2 字符串开头或结尾匹配 2.3 用Shell通配符匹配字符串 2.4 字符串匹配和搜索 2.5 字符串搜索和替换 2.6 字符串忽略大小写的搜索替换 2.7 最短匹配模式 2.8 多行匹配模式 ...

    《Python+Cookbook》第三版中文v3.0.0.pdf 熊熊

    2.3 用 Shell 通配符匹配字符串 . . . . . . . . . . . . . . . . . . . . . . . . . . 50 2.4 字符串匹配和搜索 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 2.5 字符串搜索和替换 . . . . ...

    Java2核心技术.part5

    12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带允隔符的输入 12.4.4 StringBuilder类 12.4.5随机存取流 12.5对象流 12.5.1存储可变类型的对象 12.5.2理解对象序列化文件格式 12.5.3...

    net学习笔记及其他代码应用

    答:string str = null 是不给他分配内存空间,而string str = \"\" 给它分配长度为空字符串的内存空间。 25.请详述在dotnet中类(class)与结构(struct)的异同? 答:Class可以被实例化,属于引用类型,是分配在内存的...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例110 通过正则表达式对字符串进行匹配查找 141 实例111 通过IP地址查找主机所在地 142 实例112 解决用substr()函数对中文字符串截取时出现乱码的问题 143 实例113 字符串与HTML标记相互转换 144 实例114 运用...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例110 通过正则表达式对字符串进行匹配查找 141 实例111 通过IP地址查找主机所在地 142 实例112 解决用substr()函数对中文字符串截取时出现乱码的问题 143 实例113 字符串与HTML标记相互转换 144 实例114 运用...

    Java2核心技术.part3

    12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带允隔符的输入 12.4.4 StringBuilder类 12.4.5随机存取流 12.5对象流 12.5.1存储可变类型的对象 12.5.2理解对象序列化文件格式 12.5.3...

    Java2核心技术.part1

    12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带允隔符的输入 12.4.4 StringBuilder类 12.4.5随机存取流 12.5对象流 12.5.1存储可变类型的对象 12.5.2理解对象序列化文件格式 12.5.3保存对象...

    Java2核心技术.part6

    12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带允隔符的输入 12.4.4 StringBuilder类 12.4.5随机存取流 12.5对象流 12.5.1存储可变类型的对象 12.5.2理解对象序列化文件格式 12.5.3...

    Java2核心技术.part4

    12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带允隔符的输入 12.4.4 StringBuilder类 12.4.5随机存取流 12.5对象流 12.5.1存储可变类型的对象 12.5.2理解对象序列化文件格式 12.5.3...

    Java2核心技术.part2

    12.4.2字符串记号处理器和带分隔符的文本 12.4.3读取带允隔符的输入 12.4.4 StringBuilder类 12.4.5随机存取流 12.5对象流 12.5.1存储可变类型的对象 12.5.2理解对象序列化文件格式 12.5.3...

Global site tag (gtag.js) - Google Analytics