2017-11-07 4 views
1

Ich versuche, kämpfen, um eine Nummer zu einem bestimmten CultureInfo zu normalisieren, seine Anwendung NumberFormatNormalisieren eine Zeichenkette, die eine Dezimalzahl in bestimmten CultureInfo.NumberFormat enthält

Lassen Sie uns sagen, dass ich eine Zeichenfolge haben, die auch einige Zeichen enthält, so dass ich müssen es aufzuräumen:

var cleanedInput = Regex.Replace(userInput, @"[^0-9-,'.]+", ""); 

So bin ich im Grunde halten ,' und .. Ich mache das, weil die CultureInfo, die , und die . unterschiedlich verwendet werden, um Dezimalzahlen zu trennen oder die Zahlen zu gruppieren.

, dass im Auge zu haben, wende ich die Decimal.TryParse Methode, die NumberStyle Angabe Dezimalstellen zu ermöglichen und die IFormatProvider wird dinamically auf den gewünschten „local“ CultureInfo.NumberFormat angewandt gehen werden.

decimal numericData; 
if (!decimal.TryParse(cleanedInput, NumberStyles.AllowDecimalPoint, LocaleUser.NumberFormat, out numericData)) 
    throw new Exception($"Error occurred. Could not parse:{cleanedInput} "); 

Nehmen wir an, wir geben "hi9000,99hi" ein. Sobald gereinigt, erhalten wir "9000,99". Nett. Also wenden wir das TryParse an und es gibt Decimal9000.99 zurück. Wichtiges Sprichwort, dass ich tatsächlich die es-ESCultureInfo anwende, die das , als Dezimaltrennzeichen hat. Ich erwarte grundsätzlich 9000,99 oder 9.000,99.

Der Code hebt nicht die Exception an, aber sieht so aus, als ob er nicht die CultureInfo anwendet, die ich spezifizierte.

Was fehlt mir gerade? Ich habe das Gefühl, dass Decimal.TryParse ein Schweizer Armeemesser ist, das ich gut handhabe.

Vielen Dank im Voraus.

+2

Ich bin mir nicht sicher, was genau das Problem ist, aber denken Sie daran, dass eine Dezimalzahl kein Format ist _have_. Sie geben ein Format an, wenn _der Wert angezeigt wird. Wenn Sie ihn im Debugger betrachten, wird er die Kultur verwenden, auf die Ihr Computer eingestellt ist. Wenn Sie den Wert in einem bestimmten Format sehen wollen, verwenden Sie 'decimal.ToString' oder' string.Format'. –

+1

Um zu verdeutlichen, erhebt der Code, den Sie bereitstellen, eine Ausnahme? Und "cleanedInput" ist das, was Sie erwarten, bevor Sie in den Parser gehen? –

+0

Vielen Dank für Ihre Antwort. Der Code löst die Exception nicht aus, aber die Ausgabe, die ich erhalte, wendet definitiv nicht die von mir spezifizierte CultureInfo an und nicht einmal die CultureInfo, die VS2015 verwendet, wo sie debuggt wird. – Gonzo345

Antwort

0

Verwenden Sie double.Parse, decimal.Parse oder decimal.TryParse scheint zu arbeiten. Wie wurde die CultureInfo definiert?

string value = "9000,99"; 
decimal number; 
CultureInfo culture = CultureInfo.CreateSpecificCulture("es-ES"); 

try { 
    number = decimal.Parse(value, culture); 
    decimal.TryParse(value, NumberStyles.Any, culture, out decimal num); 
    Console.WriteLine($"{culture.Name}: {value} = {number}/{num}");      
} catch (FormatException) { 
    Console.WriteLine($"{culture.Name}: Unable to parse [{value}]"); 
} 

Ausgang:

es-ES: 9000,99 = 9000.99/9000.99 
+0

Ich bekam schließlich, was ich falsch machte, und es interpretierte die endgültige Ausgabe, die von meiner tatsächlichen Maschine CultureInfo "modifiziert" wurde. BTW, die CultureInfo wurde von einer Requisite angegeben :) – Gonzo345

0

So gegeben, dass ein Dezimal wird immer eine Dezimalzahl sein und kein Format hat, wie auf den Kommentaren gesagt wurde, ich falsch die Fragen und was konzentriert wurde, war ich auf der Suche nach!

Ich verwende schließlich diese Methode:

private decimal CleanUserInput(string userInput, CultureInfo localeUser) 
{ 
    if (localeUser == null) 
     throw new Exception("A CultureInfo must be specified. "); 

    var cleanedInput = Regex.Replace(userInput, @"[^0-9-,\.']+", ""); 
    if (string.IsNullOrWhiteSpace(cleanedInput)) 
     throw new Exception("Data provided has no numbers to be parsed. "); 

    decimal numericData; 
    if (!decimal.TryParse(cleanedInput, NumberStyles.Any, localeUser, out numericData)) 
     throw new Exception($"Couldn't parse {cleanedInput} . Make sure the applied CultureInfo ({LocaleUser.DisplayName}) is the correct one. Decimal separator to be applied: <{LocaleUser.NumberFormat.NumberDecimalSeparator}> Numeric group separator to be applied: <{LocaleUser.NumberFormat.NumberGroupSeparator}>"); 

    return numericData; 
} 
Verwandte Themen