目录
1.字符类型分类
目前共有5种字符类型:
static int identifyCharType(charinput){
|
2.分词大致流程
public synchronized Lexeme next()throws IOException{ Lexeme l = null; while((l = context.getNextLexeme()) == null ){ /* * 从reader中读取数据,填充buffer * 如果reader是分次读入buffer的,那么buffer要 进行移位处理 * 移位处理上次读入的但未处理的数据 */ //从缓冲区读入数据,缓冲区默认大小为4k int available = context.fillBuffer(this.input); if(available <= 0){ //reader已经读完 context.reset(); return null; }else{ //初始化指针 //获取缓冲区的第一个字符的位置,值,类型 context.initCursor(); do{ //遍历子分词器 /* * 处理英文字符及阿拉伯数字子分词器 LetterSegmenter * 处理中文数量词的子分词器 CN_QuantifierSegmenter * 处理中文词的子分词器 CJKSegmenter * */ //调用不同的子分词器进行分词处理 for(ISegmenter segmenter : segmenters){ segmenter.analyze(context); } //字符缓冲区接近读完,需要读入新的字符 if(context.needRefillBuffer()){ break; } //向前移动指针 }while(context.moveCursor());//移动指针,不断获取之后的字符的位置,值,类型 //重置子分词器,为下轮循环进行初始化 for(ISegmenter segmenter : segmenters){ segmenter.reset(); } } //对分词进行歧义处理 this.arbitrator.process(context, configuration.isUseSmart()); //将分词结果输出到结果集,并处理未切分的单个CJK字符 context.outputToResult(); //记录本次分词的缓冲区位移 context.markBufferOffset(); } return l; }
|
主要分为三步:
1) 不断移动缓存区的指针,获取不同的字符的位置,值,类型
2) 调用不用的子分词器进行分词处理
3) 对最终的分词结果进行歧义处理
同时注意:IK分词器默认开启大写转小写的功能,即enable_lowercase=true
3.子分词器
IK分词器内置3种子分词器,分别是:
1)LetterSegmenter:处理英文字母和阿拉伯字母的子分词器
2)CN_QuantifierSegmenter:处理中文数量词的子分词器
3)CJKSegmenter:处理中文词的子分词器
每个具体的分词由以下结构体表示:
/** * IK词元对象 */ public class Lexeme implements Comparable<Lexeme>{ //lexemeType常量 //未知 public static final int TYPE_UNKNOWN = 0; //英文 public static final int TYPE_ENGLISH = 1; //数字 public static final int TYPE_ARABIC = 2; //英文数字混合 public static final int TYPE_LETTER = 3; //中文词元 public static final int TYPE_CNWORD = 4; //中文单字 public static final int TYPE_CNCHAR = 64; //日韩文字 public static final int TYPE_OTHER_CJK = 8; //中文数词 public static final int TYPE_CNUM = 16; //中文量词 public static final int TYPE_COUNT = 32; //中文数量词 public static final int TYPE_CQUAN = 48; /*词元的起始位移,指缓冲区的偏移量,因为不可能一次性把所有数据分析完,必须分段分析,因此 *offset指的是每次读取缓存区的偏移量(和起始位置比较)*/ private int offset; //特定缓冲区内词元的起始位置 private int begin; //词元的长度 private int length; //词元文本 private String lexemeText; //词元类型 |