⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matchnamerule.cs

📁 KTDictSeg 简介: KTDictSeg 是由KaiToo搜索开发的一款基于字典的简单中英文分词算法 * 主要功能: 中英文分词
💻 CS
📖 第 1 页 / 共 3 页
字号:
                                Traffic(beforeWord, afterWord);
                            }


                            name = name + (String)preWords[index + 1];
                            retWords.Add(name);
                            return index + 2;
                        }
                    }
                }
            }

            //统计
            if (m_AutoStudy)
            {
                String afterWord = null;
                String beforeWord = null;
                if (retWords.Count > 0)
                {
                    beforeWord = retWords[retWords.Count-1];
                }

                if (index + 2 < preWords.Count)
                {
                    afterWord = preWords[index + 1];
                }

                Traffic(beforeWord, afterWord);
            }

            retWords.Add(name);
            return index + 1;
        }




        /// <summary>
        /// 匹配姓位于单词尾部的情况
        /// </summary>
        /// <param name="preWords"></param>
        /// <param name="index"></param>
        /// <param name="retWords"></param>
        /// <returns></returns>
        private int MatchFamilyNameInTail(List<String> preWords, int index, List<String> retWords)
        {
            if (retWords.Count < 1)
            {
                return -1;
            }

            String curWord = (String)retWords[retWords.Count-1];

            if (curWord.Length < 2)
            {
                return -1;
            }

            String nextWord = (String)preWords[index];

            if (nextWord.Length > 2)
            {
                return -1;
            }

            String familyName;

            //单姓
            familyName = curWord[curWord.Length - 1].ToString();

            if (m_FamilyNameTbl[familyName] == null)
            {
                familyName = curWord.Substring(curWord.Length-2, 2);
                if (m_FamilyNameTbl[familyName] == null)
                {
                    return -1;
                }
            }

            String remain = curWord.Substring(0, curWord.Length - familyName.Length);

            if (retWords.Count > 0)
            {
                //重新组合前面的词,并判断词性匹配
                String newWord = null;
                bool isReg;

                if (retWords.Count > 1)
                {
                    newWord = retWords[retWords.Count - 2] + remain;
                    m_Pos.GetPos(newWord, out isReg);
                    if (!isReg)
                    {
                        newWord = null;
                    }
                    else
                    {
                        if (!m_PosBinRule.MatchNameInTail(newWord))
                        {
                            newWord = null;
                        }
                    }

                    if (newWord != null)
                    {
                        retWords.RemoveAt(retWords.Count - 1);
                        retWords.RemoveAt(retWords.Count - 1);
                    }

                }

                if (newWord == null)
                {
                    newWord = remain;
                    m_Pos.GetPos(newWord, out isReg);
                    if (!isReg)
                    {
                        if (retWords.Count > 1)
                        {
                            newWord = retWords[retWords.Count - 2] + remain;
                            retWords.RemoveAt(retWords.Count - 1);
                        }
                    }
                    else
                    {
                        if (!m_PosBinRule.MatchNameInTail(newWord))
                        {
                            newWord = null;
                        }
                    }

                    if (newWord != null)
                    {
                        retWords.RemoveAt(retWords.Count - 1);
                    }
                }

                if (newWord != null)
                {
                    retWords.Add(newWord);
                }
                else
                {
                    return -1;
                }
            }

            String name = familyName + nextWord;

            if (name.Length - familyName.Length == 1)
            {
                //单字名 还要尝试是否是双字名

                if (index < preWords.Count - 1)
                {
                    String nnext = name + (String)preWords[index + 1];
                    nnext = nnext.Substring(familyName.Length, nnext.Length - familyName.Length);

                    if (nnext.Length <= 2)
                    {
                        if (!m_PosBinRule.MatchNameInHead(nnext))
                        {
                            name = name + (String)preWords[index + 1];
                            retWords.Add(name);
                            return index + 2;
                        }
                    }
                }
            }

            retWords.Add(name);
            return index + 1;
        }

        /// <summary>
        /// 简单匹配。
        /// 判断第一个单词是不是姓,如果是,
        /// 如果是单字姓,再看第二个单词是不是单子,
        /// 如果是,看两个词是否可以组成双字姓。
        /// 不是也一样按上面逻辑判断是否是双字姓。
        /// 确认姓后,看前面的单词是否是高频姓名前缀,
        /// 如果是,确认为姓名,看后面的单词是否是高频
        /// 姓名后缀,如果是,直接返回姓,如果不是,后面
        /// 单词为两个单字,则判断第二个单字是否是高频后缀
        /// 不是,合并为一个名字,是只取第一个单子。
        /// 如果前面不是高频姓名前缀,判断后面如果两个字之内
        /// 是否有高频姓名后缀,有则确认为姓名。
        /// 确认姓名后,对前后单词加入单词前后缀,并将姓名进行
        /// 记录,等到一定出现频率后,将新的姓名加入词库。
        /// </summary>
        /// <param name="preWords"></param>
        /// <param name="index"></param>
        /// <param name="retWords"></param>
        /// <returns></returns>
        private int SimpleMatch(List<String> preWords, int index, List<String> retWords)
        {
            String prefix = null;
            int curIndex = index;

            //获取前缀
            if (retWords.Count >= 1)
            {
                prefix = (String)retWords[retWords.Count - 1];
            }

            //如果后面没有词了,则不再匹配
            if (preWords.Count - index < 2)
            {
                return -1;
            }

            //第一个单词
            String fstWord = (String)preWords[index];

            //如果第一个单词长度大于2,通常不是中文姓氏,退出姓名匹配
            if (fstWord.Length > 2)
            {
                return -1;
            }

            String famlilyName = null;

            if (m_FamilyNameTbl[fstWord] == null)
            {
                //长度为2的单词,如果不是中文姓氏,则直接退出姓名匹配
                if (fstWord.Length == 2)
                {
                    return -1;
                }
            }
            else
            {
                //此时匹配出来的姓氏如果是单字,还需要继续匹配,看是不是双字姓
                famlilyName = fstWord;
            }

            if (fstWord.Length == 1)
            {
                if (preWords[index + 1].Length == 1)
                {
                    if (m_FamilyNameTbl[fstWord + preWords[index + 1]] != null)
                    {
                        famlilyName = fstWord + preWords[index + 1];
                        curIndex++;
                    }
                }
            }

            if (famlilyName == null)
            {
                return -1;
            }

            //通过前缀判断是否是姓名
            bool isNameByPrefix = false;

            //通过后缀判断是否是姓名
            bool isNameByPostfix = false;

            //先判断有没有姓名前缀
            if (prefix != null)
            {
                if (m_ChsNameTraffic.MaybeNameByBefore(prefix))
                {
                    isNameByPrefix = true;
                }
            }

            int postfixPosition = curIndex + 1;

            //如果没有前缀,又到了最后
            //只有在合并双字姓氏时会发生
            if (preWords.Count - curIndex < 2)
            {
                isNameByPostfix = false;
            }
            else if (preWords[postfixPosition].Length > 2)
            {
                //如果姓氏后面的词长度大于2,通常不是人名
                isNameByPostfix = false;
            }
            else
            {
                if (m_ChsNameTraffic.MaybeNameByAfter(preWords[postfixPosition]))
                {
                    //如果姓后面直接跟后缀,直接返回姓

                    isNameByPostfix = true;
                }
                else
                {
                    if (preWords[postfixPosition].Length == 1)
                    {
                        //如果姓后面跟一个单字,还要判断单字后面是后缀还是单字
                        postfixPosition++;

                        if (preWords.Count - postfixPosition < 1)
                        {
                            //已经到最后
                            isNameByPostfix = false;
                        }
                        else if (preWords[postfixPosition][0] < 0x4e00 || preWords[postfixPosition][0] > 0x9fa5)
                        {
                            //如果后面不是汉字,则结束
                            isNameByPostfix = false;
                        }
                        else if (m_ChsNameTraffic.MaybeNameByAfter(preWords[postfixPosition]))
                        {
                            //是后缀
                            isNameByPostfix = true;
                        }
                        else
                        {
                            //不是后缀
                            if (preWords[postfixPosition].Length == 1)
                            {
                                //单字名后面还有一个单字,可能是双字名
                                postfixPosition++;

                                if (preWords.Count - postfixPosition < 1)
                                {
                                    //已经到最后
                                    isNameByPostfix = false;
                                }
                                else if (preWords[postfixPosition][0] < 0x4e00 || preWords[postfixPosition][0] > 0x9fa5)
                                {
                                    //如果后面不是汉字,则结束
                                    isNameByPostfix = false;
                                }
                                else if (m_ChsNameTraffic.MaybeNameByAfter(preWords[postfixPosition]))
                                {
                                    //是后缀
                                    isNameByPostfix = true;
                                }
                                else
                                {
                                    //不是后缀
                                    isNameByPostfix = false;
                                }
                            }
                            else
                            {
                                //单字后面跟多字,不可能合并为一个名字
                                isNameByPostfix = false;
                            }
                        }
                    }
                    else
                    {
                        //如果姓后面跟一个单字,还要判断单字后面是后缀还是单字
                        postfixPosition++;

                        if (preWords.Count - postfixPosition < 1)
                        {
                            //已经到最后
                            isNameByPostfix = false;
                        }
                        else if (preWords[postfixPosition][0] < 0x4e00 || preWords[postfixPosition][0] > 0x9fa5)
                        {
                            //如果后面不是汉字,则结束
                            isNameByPostfix = false;
                        }
                        else if (m_ChsNameTraffic.MaybeNameByAfter(preWords[postfixPosition]))
                        {
                            //是后缀
                            isNameByPostfix = true;
                        }
                        else
                        {
                            isNameByPostfix = true;
                        }
                    }
                }
            }

            if (isNameByPostfix || isNameByPrefix)
            {
                //如果有前缀或后缀确认,则认为是人名
                String name = famlilyName;
                for (int i = curIndex + 1; i < postfixPosition; i++)
                {
                    name += preWords[i];
                }

                retWords.Add(name);

                if (AutoStudy)
                {
                    if (TrafficUnknownWordHandle != null)
                    {
                        TrafficUnknownWordHandle(name, T_POS.POS_A_NR);
                    }
                }

                return postfixPosition;
            }
            else
            {
                return -1;
            }
        }


        public int ProcRule(List<String> preWords, int index, List<String> retWords)
        {

            return SimpleMatch(preWords, index, retWords);

/*
            int idx;
            idx = MatchFamilyNameInTailByTraffic(preWords, index, retWords);

            if (idx < -1)
            {
                return -1;
            }

            if (idx < 0)
            {
                idx = MatchFamilyNameInHead(preWords, index, retWords);
                return idx;
            }
            else
            {
                return idx;
            }

            if (idx < -1)
            {
                return -1;
            }

            if (idx < 0)
            {
                return MatchFamilyNameInTail(preWords, index, retWords);
            }
            else
            {
                return idx;
            }
 */ 
        }

        #endregion
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -