2016-03-15 4 views
1

Я посмотрел на несколько вопросов по SO разборе валюты, лучший (рекомендуется) способ, кажется, один я пытаюсь ниже:Анализировать значение с символом валюты

var payout = decimal.Parse("$2.10", NumberStyles.Currency | NumberStyles.AllowDecimalPoint); 

Однако, он бросает и исключение: Строка ввода не в правильном формате.

Я не знаю, что я делаю неправильно?

EDIT

Спасибо за ответы. Дополнительная информация: жестко закодированное значение валюты, которое я дал, было просто примером. У меня есть список валют:

€ 2,66

$ 2,10

$ 5,55

т.д.

Я не могу определить данные культуры заранее. Есть идеи?

+3

Перемещение в другую страну (использующую $ в качестве символа валюты и '.' Как десятичный разделитель). В качестве альтернативы читайте «CultureInfo», поскольку это может быть дешевле. –

+0

Строка валюты будет динамической, а не жесткой, как мой пример. Например. $ 2,10, € 2,66 и т. Д. Как я узнаю «Культурную информацию» заранее? – l3utterfly

+0

Убежать ... Невозможно правильно проанализировать $ 3,100 без знания CultureInfo, используемого для форматирования значения. Проверка против списка всех символов валюты и наделение того, что вы правильно определили десятичный разделитель, - это самая безопасная ставка (я бы не рекомендовал эту ставку делать так). –

ответ

2

Подобный подход @ ун-счастливчик упоминаются как один из ответа, я попытался сделать это родовым и работу для каждого Symbol/Format

public static decimal ParseCurrencyWithSymbol(string input) 
{ 
    var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures) 
     .GroupBy(c=> c.NumberFormat.CurrencySymbol) 
     .ToDictionary(c=> c.Key, c=>c.First()); 


    var culture = cultures.FirstOrDefault(c=>input.Contains(c.Key)); 

    decimal result = 0; 
    if(!culture.Equals(default(KeyValuePair<string,CultureInfo>))) 
    { 
     result = decimal.Parse(input, NumberStyles.Currency | NumberStyles.AllowDecimalPoint, culture.Value); 
    } 
    else 
    { 
     if(!decimal.TryParse(input, out result)) 
     { 
      throw new Exception("Invalid number format"); 
     } 
    } 

    return result; 
} 

Использования

decimal output = ParseCurrencyWithSymbol("$2.10"); 

Рабочих Code

+0

С евро, ваш код выводит 210, что неверно, как в ЕС, «запятая» - это десятичный разделитель, а не «период» – l3utterfly

+0

@ l3utterfly ahh .. не заметил, спасибо за указание. Исправит это. –

+0

@ l3utterfly исправил его. –

0

Документы, касающиеся вашего конкретного случая, вы можете использовать следующий фрагмент кода:

var payout = decimal.Parse("$2.10".Replace("$","")); 

Если вы не знаете, что символ валюты будет, то попробуйте следующее решение:

string _money = "$2.10"; 
var payout = decimal.Parse(_money.Substring(1)); 

Работа с запятыми и десятичными точками намного сложнее: если это проблема, обратитесь к решению, заданному членом @ un-lucky.

Надеюсь, это поможет.

+0

Там действительно ничего, что могло бы помочь OP :) ... Особенно этот код, как не каждое место, помещал символ валюты впереди. –

+0

@AlexeiLevenkov Да, согласен. Этот вопрос слишком широк, при этом слишком много неопределенностей. С уважением, –

1

Вы можете попробовать так:

decimal currencyValue; 
string inputCurrency = "$12.6"; 
if (decimal.TryParse(inputCurrency, NumberStyles.Currency, CultureInfo.CreateSpecificCulture("en-US"), out currencyValue)) 
    { 
     // proceed with currencyValue 
    } 
else 
    { 
     //Show error ; Conversion failed 
    } 

Для решения всех валют вы можете использовать следующее:

 Dictionary<char, string> currencyCulture = new Dictionary<char, string>(); 
     currencyCulture.Add('$', "en-US"); 
     currencyCulture.Add('€', "en-IE"); 
     // populate all posible values here 
     decimal currencyValue; 
     string inputCurrency = "€2,66"; 
     char currencySymbol= inputCurrency.ToCharArray()[0]; 
     CultureInfo currentCulture= CultureInfo.CreateSpecificCulture(currencyCulture[currencySymbol]); 
     if (decimal.TryParse(inputCurrency, NumberStyles.Currency, currentCulture, out currencyValue)) 
     { 
      // proceed with currencyValue 
     } 
     else 
     { 
     //Show error ; Conversion failed 
     } 

Вы можете выбрать культуру имен из here

0

Как насчет CleanCurrency метод?

/// Loops each char in the string and returns only numbers, . or , 
static double? CleanCurrency(string currencyStringIn) { 
    string temp = ""; 
    int n; 
    for (int i = 0; i < currencyStringIn.Length; i++) { 
    string c = currencyStringIn.Substring(i, 1); 
    if (int.TryParse(c, out n) || c == "." || c == ",") { 
     temp += c; 
    } 
    } 
    if (temp == "") { 
    return null; 
    else { 
    return double.Parse("0" + temp); 
    } 
} 

Идея здесь состоит в том, чтобы просто получить фактическое число независимо от содержимого строки.

double? payout = CleanCurrency("$3.50"); 
+0

Как насчет этого? Идея здесь - «1500» и «1.500» - очень разные значения - нет объяснения, как ваш код решает это (в дополнение к некоторой очень сложной реализации «Regex.Replace (« $ 1.2 », @» [^ \ d, \.] "," ")') –

Смежные вопросы