while ((lexeme = ik.next()) != null) { wordName = lexeme.getLexemeText(); pos = lexeme.getBeginPosition(); System.out.println("wordName: " + wordName + " pos: " + pos); }
/** * 分词,获取下一个词元 * @return Lexeme 词元对象 * @throws IOException */ public synchronized Lexeme next()throws IOException{ if(this.context.hasNextResult()){ //存在尚未输出的分词结果 return this.context.getNextLexeme(); }else{ /* * 从reader中读取数据,填充buffer * 如果reader是分次读入buffer的,那么buffer要进行移位处理 * 移位处理上次读入的但未处理的数据 */ int available = context.fillBuffer(this.input); if(available <= 0){ //reader已经读完 context.reset(); return null; }else{ //初始化指针 context.initCursor(); do{ //遍历子分词器 for(ISegmenter segmenter : segmenters){ segmenter.analyze(context); } //字符缓冲区接近读完,需要读入新的字符 if(context.needRefillBuffer()){ break; } //向前移动指针 }while(context.moveCursor()); //重置子分词器,为下轮循环进行初始化 for(ISegmenter segmenter : segmenters){ segmenter.reset(); } } //对分词进行歧义处理 this.arbitrator.process(context, this.cfg.useSmart()); //处理未切分CJK字符 context.processUnkownCJKChar(); //记录本次分词的缓冲区位移 context.markBufferOffset(); //输出词元 if(this.context.hasNextResult()){ return this.context.getNextLexeme(); } return null; }
其中几个主要的方法说明如下:
int available = context.fillBuffer(this.input);
context.initCursor();
for(ISegmenter segmenter : segmenters){ segmenter.analyze(context); }
while(context.moveCursor());
//对分词进行歧义处理 this.arbitrator.process(context, this.cfg.useSmart());
//处理未切分CJK字符 context.processUnkownCJKChar();
记录本次分词的缓冲区位置
//记录本次分词的缓冲区位移 context.markBufferOffset();
主要流程介绍完了,并不复杂,其实IK分词算是比较简单的分词方法了,没有复杂的智能算法在里面