2016-08-03 19 views
1

ich an einem Projekt arbeite, die Daten aus einer Datei und speichern Sie es auf MySQL-Datenbank die Datei hat die folgende Zeichenfolge in mehreren FormatenC# Anzahl unterschiedliche Formate

Ava. bytes -> 147.258.369 
Ava. bytes -> 147.258.369,5 
Ava. bytes -> 147,258,369 
Ava. bytes -> 147,258,369.5 

was ist die beste Art und Weise zu analysieren erfordert konvertieren Sie eines dieser Formate in

Ava. bytes -> 147.258.369 => 147258369.0 
Ava. bytes -> 147.258.369,5 =>147258369.5 
Ava. bytes -> 147,258,369 => 147258369.0 
Ava. bytes -> 147,258,369.5 =>147258369.5 

danke!

+1

Ist das Dezimalsystem immer nur auf den zehnten? Denn was wäre, wenn Sie 147.258 und 147.258 hätten ... Sie hätten nicht genug Informationen, um zu wissen, ob Sie 147.258 oder 147.258.000 – Ryan

+1

gemeint haben. Was ist '123,456'? – SimpleVar

+0

Sind diese Daten fester Breite, wo Sie sich darauf verlassen können, dass die Dezimalstelle (falls vorhanden) immer am selben Ort ist? – DVK

Antwort

0

Sie können einen regulären Ausdruck verwenden, beliebigen Punkt oder Komma zu entfernen, die von drei Ziffern gefolgt wird, und eine Zeichenfolge ersetzt das letzte Komma für einen Zeitraum zu ersetzen, wenn es einen gibt:

string n = "147.258.369,5"; 
var r = new Regex(@"[.,](?=\d{3})"); 
string n2 = r.Replace(n, "").Replace(',', '.'); 

Edit: (. aber vermutlich wollen Sie die Zeichenfolge, da die 0,0 wichtig ist)

der String ist dann in InvariantFormat, wenn Sie es in eine Dezimalzahl analysieren wollen

Um auch die letzten .0:

if (n2.Length < 2 || n2[n2.Length - 2] != '.') 
{ 
    n2 = n2 + ".0"; 
} 
+0

Ich gebe zu, diese 3-Liner ist verlockender als meine viele Zeilen-Helfer-Methode. Aber ich fordere Sie auf, Regex zu vermeiden, wenn es nicht unbedingt notwendig ist. Regex ist hier ein Overkill und wird die Performance beeinflussen. – SimpleVar

+0

@SimpleVar Das ist ein guter Punkt, aber dieser reguläre Ausdruck muss nicht viel arbeiten (d. H. Minimales Backtracking). Es könnte eine elegante Lösung sein, die in der Praxis schnell genug ist. –

0

Ich bin im Grunde erklären die Lösung durch die Kommentare, , so können Sie nur die Kommentare lesen und allein die Idee bekommen.

Hinweis Ich verwende decimal als Endergebnis. Aber Sie können float oder double verwenden, wenn Sie möchten. Der allgemeine Ansatz bleibt gültig.

string str = "123,456.7"; 

// Check if its a simple integer (no floating point or thousands separators) 
if (str.Length <= 3) 
    return (decimal)int.Parse(str); 

// Get the floating-point character from the string 
char floatingPointChar = str[str.Length - 2]; 

// Based on the floating-point character, 
// we assure the string is in a standard format of "000,000.0" 
switch (floatPointChar) 
{ 
    case '.': 
     // If the floating point is a . 
     // the number is already in a standard format 
     break; 
    case ',': 
     // put ~ as a temporary floating-point character 
     str = str.Replace(',', '~'); 

     // turn dots into thousand separators 
     str = str.Replace('.', ','); 

     // put . as floating-point character 
     str = str.Replace('~', '.'); 
     break; 
    default: 
     // There is actually no floating point, 
     // so just make sure thousand separators are , 
     str = str.Replace('.', ','); 
     break; 
} 

// Now our string is in a standard format 
// , for thousands separators 
// . for floating point 
return decimal.Parse(str, CultureInfo.InvariantCulture); 

Edit: ich die Tatsache völlig ignoriert, dass Tausendertrenn ganz weggelassen werden kann. Siehe null Antwort für mehr Inspiration

0

Dies ist eine sehr unangenehme Art und Weise tun:

private static string FormatIntString(string input) 
    { 
     if (input.IndexOf('.') != input.LastIndexOf('.')) 
     { 
      if (input.Contains(",")) 
      { 
       //this case-> Ava.bytes -> 147.258.369,5 =>147258369.5 
       return DoFormat(input.Replace(".", "").Replace(',', '.')); 
      } 
      else 
      { 
       // this case-> Ava.bytes -> 147.258.369 => 147258369.0 
       return DoFormat(input.Replace(".", ""));     
      } 
     } 
     else 
     { 
      if (input.Contains('.')) 
      { 
       //this case -> Ava.bytes -> 147,258,369.5 =>147258369.5 
       return DoFormat(input.Replace(",", ""));     
      } 
      else 
      { 
       //this case -> Ava.bytes -> 147,258,369 => 147258369.0 
       return DoFormat(input.Replace(",", "")); 
      } 
     } 
    } 
    public static string DoFormat(string myNumber) 
    { 
     var s = string.Format("{0:0.00}", myNumber); 
     if (s[s.Length-2] != '.')    
      return (myNumber + ".0");    
     else    
      return s;    
    } 

Beachten Sie, dass dies nur funktioniert, für Saiten mit mindestens zwei ‚‘ oder ' . "

Der vereinfachte Code:

private static string FormatIntString(string input) 
    { 
     if (input.IndexOf('.') != input.LastIndexOf('.')) 
      if (input.Contains(",")) 
       return DoFormat(input.Replace(".", "").Replace(',', '.')); 
      else 
       return DoFormat(input.Replace(".", "")); 
     else    
      if (input.Contains('.')) 
       return DoFormat(input.Replace(",", "")); 
      else 
       return DoFormat(input.Replace(",", ""));    
    } 

    public static string DoFormat(string myNumber) 
    { 
     var s = string.Format("{0:0.00}", myNumber); 
     if (s[s.Length - 2] != '.') 
      return (myNumber + ".0"); 
     else 
      return s; 
    }