/// <summary> /// 添加量词词元到结果集 /// </summary> /// <param name="context"></param> private void OutputCountLexeme(Context context) { if (countStart > -1 && countEnd > -1) { //生成已切分的词元 Lexeme countLexeme = new Lexeme(context.BuffOffset, countStart, countEnd - countStart + 1, Lexeme.TYPE_NUMCOUNT); context.AddLexeme(countLexeme); } }
/// <summary> /// 添加数词词元到结果集 /// </summary> /// <param name="context"></param> private void OutputNumLexeme(Context context) { if (nStart > -1 && nEnd > -1) { //生成已切分的词元 Lexeme newLexeme = new Lexeme(context.BuffOffset, nStart, nEnd - nStart + 1, Lexeme.TYPE_NUM); context.AddLexeme(newLexeme); fCaN = true; } }
/// <summary>* /// 处理数字字母混合输出 /// 如:windos2000 | [email protected] /// </summary> private bool ProcessMixLetter(char input, Context context) { bool needLock = false; if (start == -1) {//当前的分词器尚未开始处理字符 if (IsAcceptedCharStart(input)) { //记录起始指针的位置,标明分词器进入处理状态 start = context.Cursor; end = start; } } else {//当前的分词器正在处理字符 if (IsAcceptedChar(input)) { //输入不是连接符 // if(!isLetterConnector(input)){ //记录下可能的结束位置,如果是连接符结尾,则忽略 // end = context.getCursor(); // } //不在忽略尾部的链接字符 end = context.Cursor; } else { //生成已切分的词元 Lexeme newLexeme = new Lexeme(context.BuffOffset, start, end - start + 1, Lexeme.TYPE_LETTER); context.AddLexeme(newLexeme); //设置当前分词器状态为“待处理” start = -1; end = -1; } } //context.getCursor() == context.getAvailable() - 1读取缓冲区最后一个字符,直接输出 if (context.Cursor == context.Available - 1) { if (start != -1 && end != -1) { //生成已切分的词元 Lexeme newLexeme = new Lexeme(context.BuffOffset, start, end - start + 1, Lexeme.TYPE_LETTER); context.AddLexeme(newLexeme); } //设置当前分词器状态为“待处理” start = -1; end = -1; } //判断是否锁定缓冲区 if (start == -1 && end == -1) { //对缓冲区解锁 needLock = false; } else { needLock = true; } return needLock; }
// /// <summary>* // /// 处理纯阿拉伯字符输出 // /// @param input // /// @param context // /// @return // /// </summary> // private bool processPureArabic(char input , Context context){ // bool needLock = false; // // if(numberStart == -1){//当前的分词器尚未开始处理数字字符 // if(CharacterHelper.isArabicNumber(input)){ // //记录起始指针的位置,标明分词器进入处理状态 // numberStart = context.getCursor(); // numberEnd = numberStart; // } // }else {//当前的分词器正在处理数字字符 // if(CharacterHelper.isArabicNumber(input)){ // //记录当前指针位置为结束位置 // numberEnd = context.getCursor(); // }else{ // //生成已切分的词元 // Lexeme newLexeme = new Lexeme(context.getBuffOffset() , numberStart , numberEnd - numberStart + 1 , Lexeme.TYPE_LETTER); // context.addLexeme(newLexeme); // //设置当前分词器状态为“待处理” // numberStart = -1; // numberEnd = -1; // } // } // // //context.getCursor() == context.getAvailable() - 1读取缓冲区最后一个字符,直接输出 // if(context.getCursor() == context.getAvailable() - 1){ // if(numberStart != -1 && numberEnd != -1){ // //生成已切分的词元 // Lexeme newLexeme = new Lexeme(context.getBuffOffset() , numberStart , numberEnd - numberStart + 1 , Lexeme.TYPE_LETTER); // context.addLexeme(newLexeme); // } // //设置当前分词器状态为“待处理” // numberStart = -1; // numberEnd = -1; // } // // //判断是否锁定缓冲区 // if(numberStart == -1 && numberEnd == -1){ // //对缓冲区解锁 // needLock = false; // }else{ // needLock = true; // } // return needLock; // } /// <summary>* /// 处理纯英文字母输出 /// @param input /// @param context /// @return /// </summary> private bool ProcessEnglishLetter(char input, Context context) { bool needLock = false; if (letterStart == -1) {//当前的分词器尚未开始处理数字字符 if (CharacterHelper.IsEnglishLetter(input)) { //记录起始指针的位置,标明分词器进入处理状态 letterStart = context.Cursor; letterEnd = letterStart; } } else {//当前的分词器正在处理数字字符 if (CharacterHelper.IsEnglishLetter(input)) { //记录当前指针位置为结束位置 letterEnd = context.Cursor; } else { //生成已切分的词元 Lexeme newLexeme = new Lexeme(context.BuffOffset, letterStart, letterEnd - letterStart + 1, Lexeme.TYPE_LETTER); context.AddLexeme(newLexeme); //设置当前分词器状态为“待处理” letterStart = -1; letterEnd = -1; } } //context.getCursor() == context.getAvailable() - 1读取缓冲区最后一个字符,直接输出 if (context.Cursor == context.Available - 1) { if (letterStart != -1 && letterEnd != -1) { //生成已切分的词元 Lexeme newLexeme = new Lexeme(context.BuffOffset, letterStart, letterEnd - letterStart + 1, Lexeme.TYPE_LETTER); context.AddLexeme(newLexeme); } //设置当前分词器状态为“待处理” letterStart = -1; letterEnd = -1; } //判断是否锁定缓冲区 if (letterStart == -1 && letterEnd == -1) { //对缓冲区解锁 needLock = false; } else { needLock = true; } return needLock; }
public void NextLexeme(char[] segmentBuff, Context context) { Hit hit; //读取当前位置的char char input = segmentBuff[context.Cursor]; if (CharacterHelper.IsCJKCharacter(input)) {//是(CJK)字符,则进行处理 if (hitList.Count > 0) { //处理词段队列 Hit[] tmpArray = hitList.ToArray(); foreach (Hit tempHit in tmpArray) { hit = Dictionary.MatchWithHit(segmentBuff, context.Cursor, tempHit); if (hit.IsMatch) {//匹配成词 //判断是否有不可识别的词段 if (hit.Begin > doneIndex + 1) { //输出并处理从doneIndex+1 到 seg.start - 1之间的未知词段 ProcessUnknown(segmentBuff, context, doneIndex + 1, hit.Begin - 1); } //输出当前的词 Lexeme newLexeme = new Lexeme(context.BuffOffset, hit.Begin, context.Cursor - hit.Begin + 1, Lexeme.TYPE_CJK_NORMAL); context.AddLexeme(newLexeme); //更新goneIndex,标识已处理 if (doneIndex < context.Cursor) { doneIndex = context.Cursor; } if (hit.IsPrefix) {//同时也是前缀 } else { //后面不再可能有匹配了 //移出当前的hit hitList.Remove(hit); } } else if (hit.IsPrefix) {//前缀,未匹配成词 } else if (hit.IsUnmatch) {//不匹配 //移出当前的hit hitList.Remove(hit); } } } //处理以input为开始的一个新hit hit = Dictionary.MatchInMainDict(segmentBuff, context.Cursor, 1); if (hit.IsMatch) {//匹配成词 //判断是否有不可识别的词段 if (context.Cursor > doneIndex + 1) { //输出并处理从doneIndex+1 到 context.Cursor- 1之间的未知 ProcessUnknown(segmentBuff, context, doneIndex + 1, context.Cursor - 1); } //输出当前的词 Lexeme newLexeme = new Lexeme(context.BuffOffset, context.Cursor, 1, Lexeme.TYPE_CJK_NORMAL); context.AddLexeme(newLexeme); //更新doneIndex,标识已处理 if (doneIndex < context.Cursor) { doneIndex = context.Cursor; } if (hit.IsPrefix) {//同时也是前缀 //向词段队列增加新的Hit hitList.AddLast(hit); //Todo:代码不同 } } else if (hit.IsPrefix) {//前缀,未匹配成词 //向词段队列增加新的Hit hitList.AddLast(hit); } else if (hit.IsUnmatch) {//不匹配,当前的input不是词,也不是词前缀,将其视为分割性的字符 if (doneIndex >= context.Cursor) { //当前不匹配的字符已经被处理过了,不需要再processUnknown return; } //输出从doneIndex到当前字符(含当前字符)之间的未知词 ProcessUnknown(segmentBuff, context, doneIndex + 1, context.Cursor); //更新doneIndex,标识已处理 doneIndex = context.Cursor; } } else {//输入的不是中文(CJK)字符 if (hitList.Count > 0 && doneIndex < context.Cursor - 1) { foreach (Hit tempHit in hitList) { //判断是否有不可识别的词段 if (doneIndex < tempHit.End) { //输出并处理从doneIndex+1 到 seg.end之间的未知词段 ProcessUnknown(segmentBuff, context, doneIndex + 1, tempHit.End); } } } //清空词段队列 hitList.Clear(); //更新doneIndex,标识已处理 if (doneIndex < context.Cursor) { doneIndex = context.Cursor; } } //缓冲区结束临界处理 if (context.Cursor == context.Available - 1) { //读取缓冲区结束的最后一个字符 if (hitList.Count > 0 //队列中还有未处理词段 && doneIndex < context.Cursor) {//最后一个字符还未被输出过 foreach (Hit tempHit in hitList) { //判断是否有不可识别的词段 if (doneIndex < tempHit.End) { //输出并处理从doneIndex+1 到 seg.end之间的未知词段 ProcessUnknown(segmentBuff, context, doneIndex + 1, tempHit.End); } } } //清空词段队列 hitList.Clear(); } //判断是否锁定缓冲区 if (hitList.Count == 0) { context.UnlockBuffer(this); } else { context.LockBuffer(this); } }
/// <summary> /// 处理未知词段 /// </summary> /// <param name="segmentBuff"></param> /// <param name="context"></param> /// <param name="uBegin">起始位置</param> /// <param name="uEnd">终止位置</param> private void ProcessUnknown(char[] segmentBuff, Context context, int uBegin, int uEnd) { Lexeme newLexeme = null; Hit hit = Dictionary.MatchInPrepDict(segmentBuff, uBegin, 1); if (hit.IsUnmatch) {//不是副词或介词 if (uBegin > 0) {//处理姓氏 hit = Dictionary.MatchInSurnameDict(segmentBuff, uBegin - 1, 1); if (hit.IsMatch) { //输出姓氏 newLexeme = new Lexeme(context.BuffOffset, uBegin - 1, 1, Lexeme.TYPE_CJK_SN); context.AddLexeme(newLexeme); } } } //以单字输出未知词段 for (int i = uBegin; i <= uEnd; i++) { newLexeme = new Lexeme(context.BuffOffset, i, 1, Lexeme.TYPE_CJK_UNKNOWN); context.AddLexeme(newLexeme); } hit = Dictionary.MatchInPrepDict(segmentBuff, uEnd, 1); if (hit.IsUnmatch) {//不是副词或介词 int length = 1; while (uEnd < context.Available - length) {//处理后缀词 hit = Dictionary.MatchInSuffixDict(segmentBuff, uEnd + 1, length); if (hit.IsMatch) { //输出后缀 newLexeme = new Lexeme(context.BuffOffset, uEnd + 1, length, Lexeme.TYPE_CJK_SF); context.AddLexeme(newLexeme); break; } if (hit.IsUnmatch) { break; } length++; } } }