本文共 1260 字,大约阅读时间需要 4 分钟。
先看看下面几个概念:
分析器Analyzer
分词器Tokenizer
过滤器Filter
Tokenizer负责把词分开
Filter负责对分开的词进行处理
Analyzer包装组合Tokenizer和Filter以满足特定的分词需求
力琦已经写了几种不同的
WhitespaceAnalyzer();
SimpleAnalyzer();
StopAnalyzer();
StandardAnalyzer();
其中前三个的切分比较简单,只以空格作为分隔符,这里我就不打算解释了.
重点是StandardAnalyzer();
被这个分析器作用后,像这句话"we are 中国人"就会变成"[we] [are] [中] [国] [人]"
明显看到他根本就没有对中文进行词级上的切分,只是笼统地进行字切分.
那为什么呢?还是从代码上解释吧:
在/src/java/org/apache/lucene/analysis下我们可以看到有独立的一个包standard
就知道这个分析器有多么特别了。里面有一个文件StandardTokenizer.jj
整个决定性的东西都在里面了,
其中的
<ALPHANUM: (<LETTER>|<DIGIT>|<KOREAN>)+ >
//说明了英语的匹配正则表达
//.....省略无数行
| < CJ: // Chinese, Japanese
[
"/u3040"-"/u318f",
"/u3300"-"/u337f",
"/u3400"-"/u3d2d",
"/u4e00"-"/u9fff",
"/uf900"-"/ufaff"
]
>
说明了中文字符的unicode的范围(跟日文放在一起了),而且是一个字符成为一个token的.
然后我们再看看
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case ALPHANUM:
token = jj_consume_token(ALPHANUM);
break;
//...........中间省略了无数行
case CJ:
token = jj_consume_token(CJ);
break;
case 0:
token = jj_consume_token(0);
break;
.......
可以看到,每遇到一个中文字,就进行分词
还是举个例子吧!不然估计很多人都会晕了的.
"we are 中国人"这个例子
由于<ALPHANUM: (<LETTER>|<DIGIT>|<KOREAN>)+ >(注意后面的这个加号)
所以we是一个token,遇到空格,是正则匹配到此为止,再下一次成功匹配are,遇到空格,得到另一个token:are
然后倒了"中",由于是CJ,所以只是两个字节的,直接匹配成功,进到下一个匹配"国".
如果对这个jj文件有所改动,就要用JavaCC(JavaCompilerCompiler,纯Java的词法分析生成器)重新生成几个重要的.java文件了.
转载地址:http://ahivi.baihongyu.com/