参考:http://grunt1223.iteye.com/blog/969197
Analyzer,或者说文本分析的过程, 实质上是将输入文本转化为文本特征向量的过程 。这里所说的文本特征,可以是词或者是短语。它主要包括以下四个步骤:
1、分词,将文本解析为单词或短语
2、归一化,将文本转化为小写
3、停用词处理,去除一些常用的、无意义的词
4、提取词干,解决单复数、时态语态等问题
Lucene Analyzer包含两个核心组件,Tokenizer以及TokenFilter。两者的区别在于,前者在字符级别处理流,而后者则在词语级别处理流。Tokenizer是Analyzer的第一步,其构造函数接收一个Reader作为参数,而TokenFilter则是一个类似拦截器的东东,其参数可以使TokenStream、Tokenizer,甚至是另一个TokenFilter。整个Lucene Analyzer的过程如下图所示:
上图中的一些名词的解释如下表所示:
| 类 | 说明 |
| Token | 表示文中出现的一个词,它包含了词在文本中的位置信息 |
| Analyzer | 将文本转化为TokenStream的工具 |
| TokenStream | 文本符号的流 |
| Tokenizer | 在字符级别处理输入符号流 |
| TokenFilter | 在字符级别处理输入符号流,其输入可以是TokenStream、Tokenizer或者TokenFilter |
lucene分词自定义
TokenStream继承关系图如下:
StopAnalyzer,StandardAnalyze,WhitespaceAnalyzer,SimpleAnalyzer,KeyWordAnalyzer都继承自父类Analyzer。
因此只要实现父类的虚方法tokenStream 就可以实现分析。
分词的切分算法由继承自父类Tokenizer的方法
public final boolean incrementToken() throws IOException 来实现。
因此自定义继承类Tokenizer并实现其incrementToken算法就可以实现自定义的分词。
//自定义禁用分词器
public class UserDefinedAnalyzer extends Analyzer{
//定义禁用词集合
private Set stops;
//无参构造器使用默认的禁用词分词器
public UserDefinedAnalyzer (){
stops = StopAnalyzer.ENGLISH_STOP_WORDS_SET;
}
/**
* 传一个禁用词数组
* @param sws
*/
public UserDefinedAnalyzer (String[] sws){
//使用stopFilter创建禁用词集合
stops=StopFilter.makeStopSet(Version.LUCENE_35,sws,true);
//将默认的禁用词添加进集合
stops.addAll(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
}
/**
* 自定义分词器
*/
@Override
public TokenStream tokenStream(String str, Reader reader) {
//读取原始Reader数据的一定是Tokenizer类,这里使用的是LetterTokenizer
return new StopFilter(Version.LUCENE_35,
new LowerCaseFilter(Version.LUCENE_35,
new LetterTokenizer(Version.LUCENE_35, reader)),stops);
}
public static void displayToken(String str,Analyzer a) {
try {
TokenStream stream = a.tokenStream("content",new StringReader(str));
//创建一个属性,这个属性会添加流中,随着这个TokenStream增加
CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);
while(stream.incrementToken()) {
System.out.print("["+cta+"]");
}
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试类
public class Test {
public static void main(String[] args) {
Analyzer a1=new UserDefinedAnalyzer(new String[]{"my","name"});
//Analyzer a1=new UserDefinedAnalyzer();
String str="my name is paul";
UserDefinedAnalyzer.displayToken(str, a1);
}
}

