/// <summary> 一(文档)对多(实例) </summary>
        /// <param name="textitem">实例文本</param>
        /// <param name="docitem">文档元素</param>
        /// <param name="nextindex">下一个文本元素的索引</param>
        /// <returns>匹配结果</returns>
        protected static MRADocMatchCollection _DocMatchGroup(ITextItem textitem, IDocsItem docitem, ref int nextindex)
        {
            bool textiszone = textitem is ITextZone;
            bool dociszone  = docitem is IDocsCollection;

            if (textiszone)
            {
                return(null);
            }
            if (!dociszone)
            {
                return(null);
            }
            ITextZone textzone            = textitem.Parent;
            List <MRADocMatchItem> matchs = new List <MRADocMatchItem>();

            if (docitem is IDocsGroup)
            {
                IDocsGroup            docgroup = (IDocsGroup)docitem;
                MRADocMatchCollection matchcolle = new MRADocMatchCollection(docgroup.Name, textzone);
                int i = textitem.ID, j = 0;
                for ( ; i < textzone.Items.Count && j < docgroup.Items.Count; i++)
                {
                    ITextItem sub = textzone.Items[i];
                    if (sub is ITextTrim)
                    {
                        continue;
                    }
                    {
                        MRADocMatchItem match = _DocMatch(sub, docgroup.Items[j]);
                        if (match != null)
                        {
                            matchcolle.Items.Add(match); j++; continue;
                        }
                    }
                    if (docgroup.Items[j] is IDocsCollection)
                    {
                        int ni = i + 1;
                        MRADocMatchCollection match = _DocMatchGroup(sub, docgroup.Items[j], ref ni);
                        if (match != null)
                        {
                            matchcolle.Items.Add(match); j++; i = ni - 1; continue;
                        }
                    }
                    return(null);
                }
                if (matchcolle.Items.Count() != docgroup.Items.Count())
                {
                    return(null);
                }
                nextindex = i;
                return(matchcolle);
            }
            if (docitem is IDocsCycle)
            {
                IDocsCycle            doccycle = (IDocsCycle)docitem;
                MRADocMatchCollection matchcolle = new MRADocMatchCollection(doccycle.Name, textzone);
                int i = textitem.ID, j = doccycle.IgnoreStart;
                for (; i < textzone.Items.Count; i++)
                {
                    ITextItem sub = textzone.Items[i];
                    if (sub is ITextTrim)
                    {
                        continue;
                    }
                    if (j == doccycle.Items.Count - doccycle.IgnoreEnd)
                    {
                        nextindex = i;
                    }
                    if (j >= doccycle.Items.Count)
                    {
                        j = 0;
                    }
                    {
                        MRADocMatchItem match = _DocMatch(sub, doccycle.Items[j]);
                        if (match != null)
                        {
                            matchcolle.Items.Add(match); j++; continue;
                        }
                    }
                    if (doccycle.Items[j] is IDocsCollection)
                    {
                        int ni = i + 1;
                        MRADocMatchCollection match = _DocMatchGroup(sub, doccycle.Items[j], ref ni);
                        if (match != null)
                        {
                            matchcolle.Items.Add(match); j++; i = ni - 1; continue;
                        }
                    }
                    return(null);
                }
                if (j == doccycle.Items.Count - doccycle.IgnoreEnd)
                {
                    nextindex = i;
                }
                if (matchcolle.Items.Count < doccycle.Items.Count - doccycle.IgnoreStart - doccycle.IgnoreEnd)
                {
                    return(null);
                }
                int count = matchcolle.Items.Count;
                count -= doccycle.Items.Count - doccycle.IgnoreStart - doccycle.IgnoreEnd;
                count -= count % doccycle.Items.Count;
                count += doccycle.Items.Count - doccycle.IgnoreStart - doccycle.IgnoreEnd;
                matchcolle.Items.RemoveRange(count, matchcolle.Items.Count() - count);
                return(matchcolle);
            }
            return(null);
        }
        /// <summary> 一(文档)对一(实例) </summary>
        /// <param name="textitem">实例文本</param>
        /// <param name="docitem">文档元素</param>
        /// <returns>匹配结果</returns>
        protected static MRADocMatchItem _DocMatch(ITextItem textitem, IDocsItem docitem)
        {
            // 实例是否具有区域性
            bool textiszone = textitem is ITextZone;
            // 文档是否具有区域性
            bool dociszone = docitem is IDocsCollection;

            // 单词一对一
            if (!textiszone && !dociszone)
            {
                if (docitem is IDocsWord)
                {
                    IDocsWord docword = (IDocsWord)docitem;
                    Match     match   = docword.Regex.Match(textitem.ToString());
                    if (match.Success)
                    {
                        return(new MRADocMatchWord(docword.Name, textitem));
                    }
                    return(null);
                }
                if (docitem is IDocsKeyWord)
                {
                    IDocsKeyWord dockeyword = (IDocsKeyWord)docitem;
                    if (dockeyword.Key.Keyword.Equals(textitem.ToString()))
                    {
                        return(new MRADocMatchWord(dockeyword.Name, textitem));
                    }
                    return(null);
                }
                return(null);
            }
            // 实例区域性
            if (textiszone)
            {
                ITextZone textzone = (ITextZone)textitem;
                // 文档为单个区域块
                if (docitem is IDocsZone)
                {
                    IDocsZone doczone = (IDocsZone)docitem;
                    // 匹配左右括号
                    if (doczone.Left == null || doczone.Right == null)
                    {
                        return(null);
                    }
                    ITextItem textleft  = textzone.Items.FirstOrDefault();
                    ITextItem textright = textzone.Items.LastOrDefault();
                    if (!(textleft is ITextKey))
                    {
                        return(null);
                    }
                    if (!(textright is ITextKey))
                    {
                        return(null);
                    }
                    ITextKey keyleft  = (ITextKey)textleft;
                    ITextKey keyright = (ITextKey)textright;
                    if (keyleft.KeyCore != doczone.Left.Key)
                    {
                        return(null);
                    }
                    if (keyright.KeyCore != doczone.Right.Key)
                    {
                        return(null);
                    }
                    // 内部匹配
                    MRADocMatchCollection matchcolle = new MRADocMatchCollection(doczone.Name, textzone);
                    for (int i = 1, j = 0; i < textzone.Items.Count - 1; i++)
                    {
                        ITextItem sub = textzone.Items[i];
                        if (sub is ITextTrim)
                        {
                            continue;
                        }
                        // 内部一(文档)对一(实例)匹配
                        {
                            MRADocMatchItem match = _DocMatch(sub, doczone.Items[j]);
                            if (match != null)
                            {
                                matchcolle.Items.Add(match); j++; continue;
                            }
                        }
                        // 内部一(文档)对多(实例)匹配
                        if (doczone.Items[j] is IDocsCollection)
                        {
                            int ni = i + 1;
                            MRADocMatchCollection match = _DocMatchGroup(sub, doczone.Items[j], ref ni);
                            if (match != null)
                            {
                                matchcolle.Items.Add(match); j++; i = ni - 1; continue;
                            }
                        }
                    }
                    if (matchcolle.Items.Count() != doczone.Items.Count())
                    {
                        return(null);
                    }
                    return(matchcolle);
                }
                // 文档为单个区域行
                if (docitem is IDocsLine)
                {
                    IDocsLine docline = (IDocsLine)docitem;
                    if (docline.Left == null)
                    {
                        return(null);
                    }
                    ITextItem textleft = textzone.Items.FirstOrDefault();
                    if (!(textleft is ITextKey))
                    {
                        return(null);
                    }
                    ITextKey keyleft = (ITextKey)textleft;
                    if (keyleft.KeyCore != docline.Left.Key)
                    {
                        return(null);
                    }
                    MRADocMatchCollection matchcolle = new MRADocMatchCollection(docline.Name, textzone);
                    for (int i = 1, j = 0; i < textzone.Items.Count; i++)
                    {
                        ITextItem sub = textzone.Items[i];
                        if (sub is ITextTrim)
                        {
                            continue;
                        }
                        MRADocMatchItem match = _DocMatch(sub, docline.Items[j++]);
                        if (match == null)
                        {
                            return(null);
                        }
                        matchcolle.Items.Add(match);
                    }
                    if (matchcolle.Items.Count() != docline.Items.Count())
                    {
                        return(null);
                    }
                    return(matchcolle);
                }
                // 文档为序列组
                if (docitem is IDocsGroup)
                {
                    IDocsGroup            docgroup   = (IDocsGroup)docitem;
                    MRADocMatchCollection matchcolle = new MRADocMatchCollection(docgroup.Name, textzone);
                    for (int i = 0, j = 0; i < textzone.Items.Count; i++)
                    {
                        ITextItem sub = textzone.Items[i];
                        if (sub is ITextTrim)
                        {
                            continue;
                        }
                        {
                            MRADocMatchItem match = _DocMatch(sub, docgroup.Items[j]);
                            if (match != null)
                            {
                                matchcolle.Items.Add(match); j++; continue;
                            }
                        }
                        if (docgroup.Items[j] is IDocsCollection)
                        {
                            int ni = i + 1;
                            MRADocMatchCollection match = _DocMatchGroup(sub, docgroup.Items[j], ref ni);
                            if (match != null)
                            {
                                matchcolle.Items.Add(match); j++; i = ni - 1; continue;
                            }
                        }
                        return(null);
                    }
                    if (matchcolle.Items.Count() != docgroup.Items.Count())
                    {
                        return(null);
                    }
                    return(matchcolle);
                }
                // 文档为循环组
                if (docitem is IDocsCycle)
                {
                    IDocsCycle            doccycle = (IDocsCycle)docitem;
                    MRADocMatchCollection matchcolle = new MRADocMatchCollection(doccycle.Name, textzone);
                    int i = 0, j = doccycle.IgnoreStart;
                    for (; i < textzone.Items.Count; i++)
                    {
                        ITextItem sub = textzone.Items[i];
                        if (sub is ITextTrim)
                        {
                            continue;
                        }
                        if (j >= doccycle.Items.Count)
                        {
                            j = 0;
                        }
                        {
                            MRADocMatchItem match = _DocMatch(sub, doccycle.Items[j]);
                            if (match != null)
                            {
                                matchcolle.Items.Add(match); j++; continue;
                            }
                        }
                        if (doccycle.Items[j] is IDocsCollection)
                        {
                            int ni = i + 1;
                            MRADocMatchCollection match = _DocMatchGroup(sub, doccycle.Items[j], ref ni);
                            if (match != null)
                            {
                                matchcolle.Items.Add(match); j++; i = ni - 1; continue;
                            }
                        }
                        return(null);
                    }
                    if (j != doccycle.Items.Count - doccycle.IgnoreEnd)
                    {
                        return(null);
                    }
                    return(matchcolle);
                }
                return(null);
            }
            return(null);
        }