Example #1
0
        /// <summary>
        /// 处理中文量词
        /// </summary>
        /// <param name="context"></param>
        private void ProcessQuant(AnalyzeContext context)
        {
            if (!NeedQuantScan(context))    // 如果不需要量词扫描,则直接返回
            {
                return;
            }

            if (context.CurrentCharType == CharUtil.CHAR_CHINESE)
            {
                if (_hits.Count > 0)     // 如果前面积累了一些尚未成形的量词,则优先处理这些
                {
                    var hits = _hits.ToArray();
                    _hits.Clear();                  // 先清空,然后再保存那些本轮尚未处理掉的未成形量词(比如新的尚未成形的量词)
                    for (int i = 0; i < hits.Length; i++)
                    {
                        var hit = hits[i];
                        hit = DictTrie.Instance.MatchWithHit(context.CharBuff, context.Cursor, hit);
                        if (hit.IsMatch)     // 当前尚未成形的量词 hit 加上 context.Cursor 开始的若干字符形成一个成形的量词
                        {
                            var lex = new Lexeme(context.BuffOffset, hit.Begin, context.Cursor - hit.Begin + 1, Lexeme.TYPE_CN_QUANT);
                            context.AddLexeme(lex);
                            if (hit.IsPrefix)   // 这个新成形的量词如果同时还是某个量词的前缀,则添加到 hit 列表(最大化匹配)
                            {
                                _hits.Add(hit);
                            }
                        }
                        else if (hit.IsPrefix)  // 当前尚未成形的量词 hit 加上 context.Cursor 开始的若干字符形成某个量词的前缀,则添加到 hit 列表
                        {
                            _hits.Add(hit);
                        }
                    }
                }
                // 除了与前面的尚未成形的量词进行联合,context.Cursor开始的字符另外还需要单字匹配,以发现更多可能的量词
                var singleHit = DictTrie.Instance.MatchWithQuantDict(context.CharBuff, context.Cursor, 1);
                if (singleHit.IsMatch)   // 首字成量词
                {
                    // 输出此单字量词
                    var lex = new Lexeme(context.BuffOffset, context.Cursor, 1, Lexeme.TYPE_CN_QUANT);
                    context.AddLexeme(lex);

                    if (singleHit.IsPrefix)     // 如果当前单字同时还是另一个量词的前缀
                    {
                        _hits.Add(singleHit);
                    }
                }
                else if (singleHit.IsPrefix)     // 当前单字虽未独立成量词,但是是另一个量词的前缀
                {
                    _hits.Add(singleHit);
                }
            }
            else    // 当前字符不是中文字符,则清空未成形的量词,因为已经不可能成量词了
            {
                _hits.Clear();
            }

            if (context.IsBuffConsumed())   // 如果缓冲区已经读取完毕
            {
                _hits.Clear();              // 清空尚未成形的量词,因为已经没机会成量词了
            }
        }
Example #2
0
        /// <summary>
        /// 处理中文数词
        /// </summary>
        /// <param name="context"></param>
        private void ProcessNum(AnalyzeContext context)
        {
            if (_start == -1 && _end == -1)      // 当前尚未开始处理中文数词
            {
                if (context.CurrentCharType == CharUtil.CHAR_CHINESE && _cnNums.Contains(context.CurrentChar))
                {
                    _end = _start = context.Cursor;     // 如果遇到中文数词,记录起始位置
                }
            }
            else
            {
                if (context.CurrentCharType == CharUtil.CHAR_CHINESE && _cnNums.Contains(context.CurrentChar))
                {
                    _end = context.Cursor;          // 继续匹配到中文数词,更新结束位置
                }
                else
                {
                    // 中文数词结束,输出词元
                    var lex = new Lexeme(context.BuffOffset, _start, _end - _start + 1, Lexeme.TYPE_CN_NUM);
                    context.AddLexeme(lex);
                    _end = _start = -1;
                }
            }

            if (context.IsBuffConsumed())    // 缓冲区如果读取完毕
            {
                if (_start != -1 && _end != -1)
                {
                    // 当前仍在处理中文数词,那么输出词元
                    var lex = new Lexeme(context.BuffOffset, _start, _end - _start + 1, Lexeme.TYPE_CN_NUM);
                    context.AddLexeme(lex);
                    _end = _start = -1;
                }
            }
        }
Example #3
0
 /// <summary>
 /// 处理英文或者数字组成的混合词元
 /// </summary>
 /// <param name="context"></param>
 /// <returns>当前是否是处理完状态还是正在处理中状态</returns>
 private bool ProcessMix(AnalyzeContext context)
 {
     if (_start == -1)    // 当前分词器尚未开始处理混合词元
     {
         if (CharUtil.CHAR_ARABIC == context.CurrentCharType || CharUtil.CHAR_ENGLISH == context.CurrentCharType)
         {
             _end = _start = context.Cursor;
         }
     }
     else
     {
         // 如果是英文字符或者是数字字符
         if (CharUtil.CHAR_ARABIC == context.CurrentCharType || CharUtil.CHAR_ENGLISH == context.CurrentCharType)
         {
             _end = context.Cursor;          // 更新混合词元的结束位置
         }
         // 如果是英文连接符
         else if (CharUtil.CHAR_USELESS == context.CurrentCharType && IsLetterConnector(context.CurrentChar))
         {
             _end = context.Cursor;
         }
         else
         {
             // 非有效英文或数字字符
             var lex = new Lexeme(context.BuffOffset, _start, _end - _start + 1, Lexeme.TYPE_ALPHANUM);
             context.AddLexeme(lex);
             _end = _start = -1;
         }
     }
     if (context.IsBuffConsumed())
     {
         if (_start != -1 && _end != -1)
         {
             var lex = new Lexeme(context.BuffOffset, _start, _end - _start + 1, Lexeme.TYPE_ALPHANUM);
             context.AddLexeme(lex);
             _end = _start = -1;
         }
     }
     return(_start != -1 || _end != -1);
 }
Example #4
0
        /// <summary>
        /// 处理数字词元
        /// </summary>
        /// <param name="context"></param>
        /// <returns>当前是否是处理完状态还是正在处理中状态</returns>
        private bool ProcessArabic(AnalyzeContext context)
        {
            if (_arabicStart == -1)      // 当前分词器尚未开始处理数字字符
            {
                if (context.CurrentCharType == CharUtil.CHAR_ARABIC)
                {
                    _arabicEnd = _arabicStart = context.Cursor;
                }
            }
            else                        // 当前分词器正在处理数字字符
            {
                if (context.CurrentCharType == CharUtil.CHAR_ARABIC)
                {
                    _arabicEnd = context.Cursor;
                }
                else if (context.CurrentCharType == CharUtil.CHAR_USELESS && IsNumConnector(context.CurrentChar))
                {
                    // 遇到数字之间的有效分隔符
                }
                else
                {   // 遇到非数字字符,输出数字词元
                    var lex = new Lexeme(context.BuffOffset, _arabicStart, _arabicEnd - _arabicStart + 1, Lexeme.TYPE_ARABIC);
                    context.AddLexeme(lex);
                    _arabicEnd = _arabicStart = -1;
                }
            }

            if (context.IsBuffConsumed())
            {
                if (_arabicStart != -1 && _arabicEnd != -1)
                {
                    var lex = new Lexeme(context.BuffOffset, _arabicStart, _arabicEnd - _arabicStart + 1, Lexeme.TYPE_ARABIC);
                    context.AddLexeme(lex);
                    _arabicEnd = _arabicStart = -1;
                }
            }

            return(_arabicStart != -1 || _arabicEnd != -1);
        }
Example #5
0
        /// <summary>
        /// 处理英文词元
        /// </summary>
        /// <param name="context"></param>
        /// <returns>当前是否是处理完状态还是正在处理中状态</returns>
        private bool ProcessEnglish(AnalyzeContext context)
        {
            if (_englishStart == -1)       // 当前分词器尚未开始处理英文字符
            {
                if (context.CurrentCharType == CharUtil.CHAR_ENGLISH)
                {
                    _englishStart = context.Cursor;
                    _englishEnd   = _englishStart;
                }
            }
            else
            {
                if (context.CurrentCharType == CharUtil.CHAR_ENGLISH)
                {
                    _englishEnd = context.Cursor;
                }
                else            // 遇到非英文字符,则输出英文词元
                {
                    var lex = new Lexeme(context.BuffOffset, _englishStart, _englishEnd - _englishStart + 1, Lexeme.TYPE_ENGLISH);
                    context.AddLexeme(lex);
                    _englishEnd = _englishStart = -1;
                }
            }

            if (context.IsBuffConsumed())                     // 如果缓冲区内容读取完毕
            {
                if (_englishStart != -1 && _englishEnd != -1) // 如果当前正在处理英文词元
                {
                    var lex = new Lexeme(context.BuffOffset, _englishStart, _englishEnd - _englishStart + 1, Lexeme.TYPE_ENGLISH);
                    context.AddLexeme(lex);
                    _englishEnd = _englishStart = -1;
                }
            }

            return(_englishStart != -1 || _englishEnd != -1);    // 返回是否需要锁定缓冲区
        }