2016-05-16 28 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(',','.')將其拉入到字符串數組中。基於上面概述的邏輯,可以使用數組的最後一個元素作爲小數部分,並將整個部分的第一個元素連接在一起。 (將實際代碼留作練習...)如果歧義點或逗號是字符串中的最後一個字符,這甚至會起作用:拆分數組中的最後一個元素將爲空。

注意:這將只有如果總是有一個小數點,則工作 - 否則,您將無法在千位逗號和千分位小數之間在邏輯上區分。