1

我正在尝试清除质量差的 OCR 读取的结果,尝试删除我可以安全认为是错误的所有内容。

所需的结果是一个 6 位数字字符串,因此我可以从结果中排除任何不是数字的字符。我也知道这些数字是按顺序出现的,所以任何乱序的数字也很可能是不正确的。

(是的,修复质量是最好的,但不是......他们不会/不能更改他们的文件)

我立即Trim()删除空格,因为这些最终会成为文件名,所以我也删除了所有非法字符。

我找出了哪些字符是数字,并将它们添加到字典中,对照它们所在的数组位置。这让我对数字序列有一个清晰的视觉指示,但我在如何让我的程序识别这一点的逻辑上苦苦挣扎。

使用字符串“ Oct', 2$3622 ”(实际读取错误)进行测试,理想的输出是“ 3662对人类很明显

    public String FindLongest(string OcrText)
    {
        try
        {
            Char[] text = OcrText.ToCharArray();
            List<char> numbers = new List<char>();

            Dictionary<int, char> consec = new Dictionary<int, char>();

            for (int a = 0; a < text.Length; a++)
            {
                if (Char.IsDigit(text[a]))
                {
                    consec.Add(a, text[a]);

                    // Won't allow duplicates?
                    //consec.Add(text[a].ToString(), true);
                }
            }

            foreach (var item in consec.Keys)
            {
                #region Idea that didn't work
                // Combine values with consecutive keys into new list
                // With most consecutive?
                for (int i = 0; i < consec.Count; i++)
                {
                    // if index key doesn't match loop, value was not consecutive
                    // Ah... falsely assuming it will start at 1. Won't work.
                    if (item == i)
                        numbers.Add(consec[item]);
                    else
                        numbers.Add(Convert.ToChar("#")); //string split value
                }
                #endregion
            }

            return null;
        }
        catch (Exception ex)
        {
            string message;

            if (ex.InnerException != null)
                message =
                    "Exception: " + ex.Message +
                    "\r\n" +
                    "Inner: " + ex.InnerException.Message;
            else
                message = "Exception: " + ex.Message;
            MessageBox.Show(message);

            return null;
        }
    }
4

4 回答 4

5

获得最长数字序列的一种快速而肮脏的方法是使用这样的正则表达式:

var t = "sfas234sdfsdf55323sdfasdf23";

var longest = Regex.Matches(t, @"\d+").Cast<Match>().OrderByDescending(m => m.Length).First();

Console.WriteLine(longest);

这实际上将获得所有序列,显然您可以使用 LINQ 选择其中最长的序列。

这不处理相同长度的多个序列。

于 2012-10-19T15:19:11.187 回答
1

由于您严格想要数字匹配,我建议使用匹配的正则表达式(\d+)

MatchCollection matches = Regex.Matches(input, @"(\d+)");
string longest = string.Empty;
foreach (Match match in matches) {
    if (match.Success) {
        if (match.Value.Length > longest.Length) longest = match.Value;
    }
}

这将为您提供最长长度的数字。如果您想实际比较值(这也适用于“最长长度”,但可以解决相同长度匹配的问题):

MatchCollection matches = Regex.Matches(input, @"(\d+)");
int biggest = 0;
foreach (Match match in matches) {
    if (match.Success) {
        int current = 0;
        int.TryParse(match.Value, out current);
        if (current > biggest) biggest = current;
    }
}
于 2012-10-19T15:22:40.540 回答
1

所以你只需要找到最长的#序列?为什么不使用正则表达式?

  Regex reg = new Regex("\d+");
  Matches mc = reg.Matches(input);
  foreach (Match mt in mc)
  {
     // mt.Groups[0].Value.Length is the len of the sequence
     // just find the longest
  }

只是一个想法。

于 2012-10-19T15:21:29.760 回答
1
var split = Regex.Split(OcrText, @"\D+").ToList();

var longest = (from s in split
               orderby s.Length descending
               select s).FirstOrDefault();

我建议使用 Regex.Split 使用 \D (代码中的@"\D+" )来查找所有非数字字符。然后,我将执行 Linq 查询以通过 .Length 查找最长的字符串。

如您所见,它既简单又非常易读。

于 2012-10-19T15:25:39.057 回答