IKAnalyzer分词器及lucene使用IKAnalyzer分析

更新时间:2023-10-18 17:00:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

IKAnalyzer版本 Jar包下载

IKAnalyzer3.2.8_bin 下载地址:

http://code.google.com/p/ik-analyzer/downloads/detail?name=IKAnalyzer3.2.8 bin.zip&can=2&q=

下载后包含说明及API文档(在目录doc3.2.8中)。

源码下载

http://code.google.com/p/ik-analyzer/downloads/detail?name=IKAnalyzer3.2.8 source.zip&can=2&q=

IKSegmentation浅析(纯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.loadSegmenter(); }

Reader input 是一个输入流,用于读取文件内容。 IKSegmentation的构造器,作了3个事

1、new Context(segmentBuff , isMaxWordLength) 创建上下文对象Context

context = new Context(segmentBuff , isMaxWordLength);

Contex主要是存储分词结果集和记录分词处理的游标位置。

2、Configuration.loadSegmenter() 加载词典、创建分词器

Configuration.loadSegmenter() 方法实现在加载词典,创建分词器详情如下。 /**

* 初始化子分词器实现

* (目前暂时不考虑配置扩展) * @return List */

public static List loadSegmenter(){

//初始化词典单例,如果查看getInstance()发现里面有详细的初始化词典的相关方法

Dictionary.getInstance();

List segmenters = new ArrayList(4); //处理数量词的子分词器

segmenters.add(new QuantifierSegmenter()); //处理中文词的子分词器

segmenters.add(new CJKSegmenter()); //处理字母的子分词器

segmenters.add(new LetterSegmenter()); return segmenters; }

得到Lexeme

这是IK分词器的语义单元对象,相当于Lucene中的Token词元对象。由于3.0版本被设计为独立于Lucene的Java分词器实现,因此它需要Lexeme来代表分词的结果。

调用的next()方法,会返回Lexeme 对象,如果没有下一个分词结果,会返回null。 源码如下

/**

* 获取下一个语义单元

* @return 没有更多的词元,则返回null * @throws IOException */

public synchronized Lexeme next() throws IOException { if(context.getResultSize() == 0){ /*

* 从reader中读取数据,填充buffer

* 如果reader是分次读入buffer的,那么buffer要进行移位处理

* 移位处理上次读入的但未处理的数据 */

int available = fillBuffer(input);

if(available <= 0){

context.resetContext(); return null; }else{

//分词处理

int analyzedLength = 0;

for(int buffIndex = 0 ; buffIndex < available ; buffIndex++){

//移动缓冲区指针

context.setCursor(buffIndex);

//进行字符规格化(全角转半角,大写转小写处理) segmentBuff[buffIndex] =

CharacterHelper.regularize(segmentBuff[buffIndex]); //遍历子分词器

for(ISegmenter segmenter : segmenters){

segmenter.nextLexeme(segmentBuff , context); }

analyzedLength++; /*

* 满足一下条件时,

* 1.available == BUFF_SIZE 表示buffer满载 * 2.buffIndex < available - 1 && buffIndex > available - BUFF_EXHAUST_CRITICAL表示当前指针处于临界区内

* 3.!context.isBufferLocked()表示没有segmenter在占用buffer

* 要中断当前循环(buffer要进行移位,并再读取数据的操作)

*/

if(available == BUFF_SIZE

&& buffIndex < available - 1 && buffIndex > available - BUFF_EXHAUST_CRITICAL

&& !context.isBufferLocked()){

break; } }

for(ISegmenter segmenter : segmenters){ segmenter.reset(); }

//System.out.println(available + \: \+ buffIndex); //记录最近一次分析的字符长度

context.setLastAnalyzed(analyzedLength); //同时累计已分析的字符长度

context.setBuffOffset(context.getBuffOffset() + analyzedLength);

//如果使用最大切分,则过滤交叠的短词元 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()

本文来源:https://www.bwwdw.com/article/s0xf.html

Top