Beispiel #1
0
        /// <summary>
        /// 给定若干个字符串和若干个正则表达式,生成若干个标注实例。
        /// </summary>
        /// <param name="brush">用来确定标注类型的画笔类实例</param>
        /// <param name="inputs">给定字符串</param>\
        /// <param name="patterns">正则表达式</param>
        /// <param name="fields">与正则表达式对应的字段</param>
        /// <param name="abort">提前终止条件</param>
        /// <param name="progress">进度报告</param>
        /// <returns>返回若干个标注实例</returns>
        /// <remarks>
        /// <para>生成规则(以单个字符串为例):</para>
        /// <para>1.按照标注类型的字段顺序,逐一和正则表达式相对应。字段数小于表达式数时,多余表达式忽略;字段数大于表达式数时,无表达式对应的字段始终为默认值。</para>
        /// <para>2.每个正则表达式多次提取,假设最终生成n个标注实例,则理论上每个正则都应匹配到1个或n个结果。</para>
        /// <para>3.若某个正则表达式匹配到1个结果,则n个标注实例的该字段都为该结果。</para>
        /// <para>4.若某个正则表达式匹配到1<x<n个结果,则前x个标注实例的该字段对应赋值,后(n-x)个标注实例该字段为空。</para>
        /// </remarks>
        private AnnotationBase[] GetAnnoFromRegex(BrushBase brush, string[] inputs, string[] patterns, FieldInfo[] fields = null,
                                                  Process.Abort abort = null, IProgress <int> progress = null)
        {
            if (brush == null)
            {
                return(null);
            }
            if (fields == null)
            {
                fields = brush.AnnoType.GetFields();
            }

            //所有有效的正则表达式产生的匹配结果(集合长度等同于有效字段个数)
            MatchCollection[] matches = new MatchCollection[Math.Min(fields.Length, patterns.Length)];

            List <AnnotationBase> result = new List <AnnotationBase>();

            foreach (string input in inputs)
            {
                if (abort != null && abort())
                {
                    return(null);
                }

                //正则匹配
                int maxLength = 0;
                for (int i = 0; i < matches.Length; i++)
                {
                    if (abort != null && abort())
                    {
                        return(null);
                    }
                    if (patterns[i].Length <= 0)
                    {
                        continue;
                    }

                    matches[i] = Regex.Matches(input, patterns[i]);
                    if (matches[i].Count > maxLength)
                    {
                        maxLength = matches[i].Count;
                    }
                }


                for (int i = 0; i < maxLength; i++)
                {
                    if (abort != null && abort())
                    {
                        return(null);
                    }

                    object[] values = new object[fields.Length];
                    for (int j = 0; j < values.Length; j++)
                    {
                        if (j >= matches.Length || matches[j] == null)
                        {
                            continue;
                        }

                        if (i < matches[j].Count)
                        {
                            values[j] = matches[j][i].Value;
                        }
                        else if (matches[j].Count == 1)
                        {
                            values[j] = matches[j][0].Value;
                        }
                    }
                    result.Add(brush.CreatAnnotation().SetFieldsValues(fields, values));
                }

                if (progress != null)
                {
                    progress.Report((Array.IndexOf(inputs, input) + 1) * 100 / inputs.Length);
                }
            }

            return(result.ToArray());
        }
Beispiel #2
0
        /// <summary>
        /// 计算正则表达式并写入textBox3中
        /// </summary>
        /// <param name="abort"></param>
        private void CalRegex(Process.Abort abort)
        {
            try
            {
                if (textBox2.Text.Length > 0)
                {
                    //显示的最大匹配数
                    const int max = 100;

                    //报告相关
                    GlobalMessage.Add("status", "计算正则...");

                    string[]        patterns = RegexText.GetLines();
                    MatchCollection matches  = Regex.Matches(FileContext, patterns[0]);

                    StringBuilder matchResult = new StringBuilder("");
                    int           realCount   = Math.Min(max, matches.Count);

                    //报告相关
                    GlobalMessage.Progress progress = new GlobalMessage.Progress(realCount)
                    {
                        ProgressedString = matches.Count > max ?
                                           $"就绪 {realCount}/{matches.Count}个匹配项" :
                                           $"就绪 {matches.Count}个匹配项"
                    };
                    if (matches.Count > max)
                    {
                        GlobalMessage.Add("info delay", $"匹配项过多,加载前{max}项");
                    }

                    ListViewGroup[] groups = new ListViewGroup[realCount];
                    for (int i = 0; i < realCount; i++)
                    {
                        if (abort != null && abort())
                        {
                            throw new Process.ProcessAbortException();
                        }

                        matchResult.Append(matches[i].Value.Replace("\n", @"\n") + "\r\n");
                        FieldInfo[]      fields = brushListPanel.CurrentItem.AnnoType.GetFields(FieldsOrder.BaseToSub);
                        AnnotationBase[] annos  = GetAnnoFromRegex(brushListPanel.CurrentItem,
                                                                   new string[1] {
                            matches[i].Value
                        },
                                                                   patterns.SubArray(1, patterns.Length - 1),
                                                                   fields, abort);
                        if (annos == null)
                        {
                            throw new Process.ProcessAbortException();
                        }

                        ListViewGroup group = new ListViewGroup($"Match {i} ({annos.Length})");
                        foreach (AnnotationBase anno in annos)
                        {
                            object[] values = anno.GetFieldsValues(fields);
                            group.Items.Add(new ListViewItem(values.ToStringArray()));
                        }
                        groups[i] = group;

                        //报告相关
                        progress.Report(i + 1);
                    }
                    //报告相关
                    if (realCount == 0)
                    {
                        progress.Report(progress.MaxValue);
                    }

                    Invoke(new Action(() =>
                    {
                        textBox3.Text = matchResult.ToString().Substring(0, Math.Min(textBox3.MaxLength, matchResult.Length));
                        listView1.Groups.AddRange(groups);
                        foreach (ListViewGroup group in groups)
                        {
                            listView1.Items.AddRange(group.Items);
                        }
                    }));
                }
                else
                {
                    GlobalMessage.Add("status", "就绪");
                }
            }
            catch (Process.ProcessAbortException)
            {
            }
            catch (Exception ex)
            {
                GlobalMessage.Add("status", "正则计算错误");
                GlobalMessage.Add("exception delay", ex.Message);
            }
            finally
            {
                GC.Collect();
            }
        }