2016-05-16 80 views
2

我正在使用正则表达式来解析来自OCR'd文档的数据,并且我正在努力匹配1000s逗号分隔符被误读为点的情形,并且还点被误读为逗号!正则表达式的十进制数点而不是逗号(.NET)

因此,如果真值为1234567.89打印为1,234,567.89但被误读为:

1.234,567.89

1,234.567.89

1,234,567,89

我大概可以用C#来排序,但我确信一个正则表达式可以做到这一点。任何可以提供帮助的正则表达式向导?

UPDATE:

我意识到这是一个非常愚蠢的问题为正则表达式是非常简单的捕捉所有的这些,它是那么我该如何选择来解释比赛。这将在C#中。谢谢 - 遗憾的是在此浪费你的时间!

我会标记答案德米特里,因为它接近我正在寻找。谢谢。

+1

你想捕捉什么,错误的或正确的? –

+0

对不起,当然。我实际上想要捕获所有这些包括缺少1000个逗号分隔符的文件。所以我可能自己回答了这个问题,这根本不是真正的正则表达式问题。卫生署。 –

+1

我认为如果你不知道号码应该是什么,这个问题是不可行的。你如何判断解释“,”或“是否正确”。 ? –

回答

3

请注意,这有歧义因为:

123,456 // thousand separator 
    123.456 // decimal separator 

都是可能的(123456123.456)。但是,我们可以检测到一些情况:

  1. 太多的小数点分隔符123.456.789
  2. 错误的顺序123.456,789
  3. 错误的数字计算123,45

因此,我们可以建立一个规则:分隔十进制其中一个如果是最后一个一个而不是跟随个恰好三位数(见上歧义),所有 其他分隔符应被视为千元的:

1?234?567?89 
^^^
    | | the last one, followed by two digits (not three), thus decimal 
    | not the last one, thus thousand 
    not the last one, thus thousand 

现在让我们来实现常规

private static String ClearUp(String value) { 
    String[] chunks = value.Split(',', '.'); 

    // No separators 
    if (chunks.Length <= 1)  
     return value; 

    // Let's look at the last chunk 
    // definitely decimal separator (e.g. "123,45") 
    if (chunks[chunks.Length - 1].Length != 3) 
     return String.Concat(chunks.Take(chunks.Length - 1)) + 
      "." + 
      chunks[chunks.Length - 1]; 

    // may be decimal or thousand 
    if (value[value.Length - 4] == ',')  
     return String.Concat(chunks); 
    else 
     return String.Concat(chunks.Take(chunks.Length - 1)) + 
      "." + 
      chunks[chunks.Length - 1]; 
    } 

现在让我们尝试一些测试:

String[] data = new String[] { 
    // you tests 
    "1.234,567.89", 
    "1,234.567.89", 
    "1,234,567,89", 

    // my tests 
    "123,456", // "," should be left intact, i.e. thousand separator 
    "123.456", // "." should be left intact, i.e. decimal separator 
    }; 

    String report = String.Join(Environment.NewLine, data 
    .Select(item => String.Format("{0} -> {1}", item, ClearUp(item)))); 

    Console.Write(report); 

结果是

1.234,567.89 -> 1234567.89 
    1,234.567.89 -> 1234567.89 
    1,234,567,89 -> 1234567.89 
    123,456 -> 123456 
    123.456 -> 123.456 
+0

或者,实际的代码留作德米特里的练习... :) –

+0

感谢德米特里,非常深思熟虑。正是我正在考虑的。正则表达式将提取“数字”,并在代码中确定小数点应该在哪里等我还需要考虑添加的奇怪空间,缺少1000个分隔符,Os而不是0等等,还需要最终计算以确定是否真的数字加起来! –

1

尝试此正则表达式:

\b[\.,\d][^\s]*\b 

\ B =字边界 含有:。或逗号或数字 不包含空格

1

响应更新/评论:你不需要regex来做到这一点。相反,如果您可以将数字字符串与周围空间隔离,则可以使用Split(',','.')将其拉入到字符串数组中。基于上面概述的逻辑,可以使用数组的最后一个元素作为小数部分,并将整个部分的第一个元素连接在一起。 (将实际代码留作练习...)如果歧义点或逗号是字符串中的最后一个字符,这甚至会起作用:拆分数组中的最后一个元素将为空。

注意:这将只有如果总是有一个小数点,则工作 - 否则,您将无法在千位逗号和千分位小数之间在逻辑上区分。