-
IKAnalyzer
版本
Jar
包下载
IKAnalyzer3.2.8_bin
下载地址:
/p/ik-analyzer/download
s/detail?name=IKAnalyzer3.2.8%&can=
2&q=
下载后
包含说明及
API
文档(在目录
doc
3.2.8
中)。
源码下载
/p/ik-analyz
er/downloads/detail?name=IKAnalyzer3.2.8%&ca
n=2&q=
IKSe
gmentation
浅析(纯
IK
分
词)
IKSegmentation
是
IK
中独立的分词器,
和
lucene
没有关系。
不继承,
不扩展,
不使用
lucene
相关的类。
IK
主分词器构造函数
/**
* IK
主分词器构造函数
*
@param
input
*
@param
isMaxWordLength
当为
true
时,分词器进行最大词长切分
*/
public
IKSegmentation(Reader
input
,
boolean
isMaxWordLength
){
this
.
input
=
input
segmentBuff
=
new
char
[
BUFF_SIZE
];
context
=
new
Context(
segmentBuff
,
isMaxWordLength
);
segmenters
= Configuration.<
/p>
loadSegmenter
();
}
Reader
input
是一个输入流,用于读取文件内容。
IKSegmentation
的构造器,作了
3
个事
1
、
new
Context(
segmentBuff
,
isMaxWordLength
)
创建上下文对象
Context
context
=
new
Context(
segmentBuff
,
isMaxWordLength
);
Contex
主要是存储分词结果集和记录分词处理的游标位置。
2
、
Configuration.
loadSegmenter
(
)
加载词典、创建分词器
Configuration.
lo
adSegmenter
()
方法实现在加载词典,创建分词
器详情如
下。
/**
*
初始化子分词器实现
*
(目前暂时不考虑配置扩展)
*
@return
List
*/
public
static
List
//
初始化词典单例,如果查看
getInstance<
/p>
()发现里面有详细的初始
化词典的相关方法
Dictionary.<
/p>
getInstance
();
List
segmenters
=
new
ArrayList
//
处理数量词的子分词器
segmenters
.add(
new
QuantifierSegmenter());
//
处理中文词的子分词器
segmenters
.add(
new
CJKSegmenter());
//
处理字母的子分词器
segmenters
.add(
new
LetterSegmenter());
return
segmenters
;
}
得到
Lexeme
这是
IK
分词器的语义单元对象,相当于
Lucene
中的
Token
词元对象。由于
3.0
版本被设计
为
独立于
Lucene
的
Java
分词器实现,因此它需要
Lexeme
来代表
分词的结果。
调用的
next()<
/p>
方法,会返回
Lexeme
对象,如果
没有下一个分词结果,会返回
null
。
源码如下
/**
*
获取下一个语义单元
*
@return
没有更多的词元,则返回
null
*
@throws
IOException
*/
public
synchronized
Lexeme next()
throws
IOException {
if
(<
/p>
context
.getResultSize() ==
0){
/*
*
从
r
eader
中读取数据,填充
buffer
*
如果
reader
是分次读入
p>
buffer
的,那么
buffer
要进行移位
处理
*
移位处理上次读入的但未处理的数据
*/
int
available
=
fillBuffer(
input
);
if
(
p>
available
<= 0){
context
.resetContext();
return
null
;
}
else
{
//
分词处理
int
analyzedLength
= 0;
for
(
int
buffIndex
= 0
buffIndex
<
available
buffIndex
++){
//
移动缓冲区指针
context
.setCursor(
buffI
ndex
);
//
进行字符规格化(全角转半角,
大写转小写处理)
segmentBuff
[
buffIndex
] =
CharacterHelper.
regularize
(
segmentBuff
[
bu
ffIndex
]);
//
遍历子分词器
for
(ISegmenter
segmenter
:
segmenters
){
seg
menter
.nextLexeme(
segmentBuf
f
,
context
);
}
analyzedLength
++;
/*
*
满足一下条件时,
* ble ==
BUFF_SIZE
表示
buffer
满载
* dex < available - 1 &&
buffIndex >
available - BUFF_EXHAUST_CR
ITICAL
表示当前指针处于临界区内
* 3.!erLocked()
表示没有
< br>segmenter
在占用
buffer
*
要中断当前循环
(
buffer
要进行移位,并再读取数据的
操作)<
/p>
*/
if
(<
/p>
available
==
BUFF_SIZE
&&
buffIndex
<
available
- 1
&&
buffIndex
>
available
-
BUFF_EXHAUST_CRITICAL
&&
!
context
.isBufferLocked()){
break
;
}
}
for
(ISegmenter
segmenter
:
segmenters
){
segmenter
.reset();
}
//n(available
+
:
+
buffIndex);
//
记录最近一次分析的字符长度
context
.setLastAnalyzed(
analyzedLen
gth
);
//
同时累计已分析的字符长度
context
.setBuffOffset(
context
.getBuffOffset() +
analyzedLength
);
//
如果使用最大切分,则过滤交叠
的短词元
p>
if
(
context
.isMaxWordLength()){
context
.excludeOverlap();
}
//
读取词元池中的词元
return
buildLexeme(
context
.firstLexeme());
}
}
else
{
//
读取词元池中的已有词元
return
buildLexeme(
context
.firstLexeme());
}
Lexeme
说明
??
public int
getBeginPosition()
说明:获取诧义单元的起始字符在文本中的位置
返回值:
int
,
诧义单元相对于文本的绝对起始位置
??
public int
getEndPosition()
说明:获取诧义单元的结束字符的下一个位置
返回值:
int
,
诧义单元相对于文本的绝对终止位置的下一个字符位置
??
public int
getLength()
说明:获取诧义单元包含字符串的长度
返回值:
int
,
诧义单元长度
=
getEndPosition
–
getBeginPosition
??
public String
getLexemeText()