OCR数字格式校正和转换

时间:2014-08-29 06:21:08

标签: c# regex string replace ocr

我正在使用OCR包从文档中提取货币金额值。偶尔小数点将被错误地OCR&d;作为逗号。该软件可以进行字符替换,开箱即用,但我不能只替换所有''用'。'因为"千位逗号"。该软件允许编写客户脚本,以便以各种语言验证和更正值。我正在使用C#。我已经尝试过各种方法来实现这一点,从子字符串替换到正则表达式替换,再到Double.Parse,全球化和数字样式等等。你们都建议实现以下所有转换?

12.345,67 ->  12345.67
12345.67  ->  12345.67 (no change)
12,345.67 ->  12345.67
1,234.56  ->  1234.56
1.234.56  ->  1234.56
1.234,56  ->  1234.56
123,45    ->  123.45
123.45    ->  123.45 (no change) 
1234      ->  1234.00
1,234     ->  1234.00
123       ->  123.00

编辑。根据提出的问题添加了更多示例。 注意:价值将以美元和美分计算。无需处理"十分之一"。 OCR的值将有两位或零位。

5 个答案:

答案 0 :(得分:0)

我会做2次替换和简单的检查,我不熟悉C#但是Javascript会是:

var newVal = value.replace(/[,.](?=\d{3,})/g, '').replace(',', '.');
if (newVal.indexOf('.')==-1)
  newVal = newVal + '.00';

您提供的示例是否涵盖了所有可能的情况?或者你处理的是超过2位小数,1位小数,需要额外的0,如123,4 -> 123.40

修改 已更改,1.234.567,89将显示为1234567.89,这假设货币不允许超过{{1}} 2位小数。这在日常生活中是正常的,但有些情况下,那些十分之一的分数很重要(股票市场,利率)。因此,根据用例,您可能需要更加彻底地确定哪个是小数点或1000分隔符。

正在使用 JSFiddle

答案 1 :(得分:0)

我最好的想法:

在每一行使用此正则表达式(?:[.,]?)(\d+),然后处理捕获组正常的时间。

  1. 如果一次:添加.00
  2. 如果两次:用点
  3. 加入第一个和第二个
  4. 如果更多:加入除了最后一个之外的所有内容并使用。
  5. 加入最后一个

    我不熟悉C#以提供代码示例,但如果真的需要可以进行搜索。

答案 2 :(得分:0)

OCR后清理是一项艰巨的工作。无论你做什么,你最终都会出错,所以绝对有必要进行人工检查。我的建议

  1. 尝试以更高的DPI扫描,300是旧标准,我更喜欢400。
  2. 使用图像处理工具包清除图像。如果可以,请尝试TMSSequoia,它们是荒谬的 好。
  3. 我不知道您使用的是哪种引擎,但大多数引擎都会为您估算每个角色的正确性。使用此信息
  4. 许多引擎为不同的识别块提供语言/字符集设置。如果您知道它们的位置,请尝试使用英语(美国)/数字。我曾经用它来阅读传真文件中的土耳其财务数据。
  5. 首先清除明显(Oo - > 0,l - > 1)
  6. 然后清除有问题(B - > 13,L - > 1。)
  7. 然后通过查看样品来尝试清洁。

答案 3 :(得分:0)

如果您更喜欢单个正则表达式,这个小怪物可能会做到这一点:

^
   (?:
      (?:
         (\d{1,3})
         (?: [.,] (\d{3}) )?
         (?: [.,] (\d{3}) )?
         (?: [.,] (\d{3}) )?
      )
      |
      (\d+)
   )
   (?:
      [.,] (\d\d)
   )?
$

替换为\1\2\3\4\5.\6

Demo

请注意,它只处理最高$999.999.999.999,99的金额,如果您为政府工作,可以随意添加更多[.,]组)。

答案 4 :(得分:0)

我最终做了很长的路。我不会称之为不优雅,但它比我想要的要长。

StringBuilder sb = new StringBuilder(strTotalIncGST);
if (strTotalIncGST.Length > 3)
{
    int decPos = strTotalIncGST.Length - 3;
    if (sb[decPos] == ',')
    {
        sb.Remove(decPos, 1);
        sb.Insert(decPos, ".");
    }
}
if (strTotalIncGST.Length > 7)
{
    int thouPos = strTotalIncGST.Length - 7;
    if (sb[thouPos] == '.' || sb[thouPos] == ',')
    {
        sb.Remove(thouPos, 1);
    }
}

然后使用double.TryParse()转换为double,然后使用.ToString("F2")返回字符串,以格式化为两位小数。