Parse value with Currency symbol

c# convert currency string to decimal
c'', cultureinfo currency format
price-parser
price-parser python
extract currency from text python
python currency parser
money parser python
extract price from string python

I have looked to multiple SO questions on parsing currency, the best (recommended) way seems to be the one I'm trying below:

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

However, it throws and exception: Input string is not in the correct format.

I don't know what I'm doing wrong?

EDIT

Thanks for the answers. Additional info: the hard-coded currency value I gave was just an example. I have a list of currencies:

€2,66

$2.10

$5.55

etc.

I cannot determine the culture info in advance. Any ideas?

Similar approach @un-lucky mentioned as one of the answer, I tried making it generic and work for every 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;
}

Usage

decimal output = ParseCurrencyWithSymbol("$2.10");

Working Code

C# Tutorial, The following code shows how to try to Parse currency value with currency symbol to decimal. Example. //from w� Each currency symbol is presented first as a graphic, then in two "Unicode-friendly" fonts: Code2000 and Arial Unicode MS.The graphic symbol in the first column will always be visible, but the symbols in the other columns may or may not be available, depending on which fonts are installed on your computer.

You can try like this:

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
  }

For dealing with all currencies you can use the following:

        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
        }

You can choose culture Names from here

scrapinghub/price-parser: Extract price amount and , Extract price amount and currency symbol from a raw text string - scrapinghub/ price-parser. Dim value As String Dim number As Single ' Parse a floating-point value with a thousands separator. value = "1,643.57" If Single.TryParse(value, number) Then Console.WriteLine(number) Else Console.WriteLine("Unable to parse '{0}'.", value) End If ' Parse a floating-point value with a currency symbol and a ' thousands separator. value = "$1,643

Pertinent to your particular case, you may use the following code snippet:

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

If you don't know what the currency symbol would be, then try the following solution:

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

Dealing with commas and decimal points is much more difficult: if this is the issue, refer to the solution given by member @un-lucky.

Hope this may help.

Currency Formatting, The 'parse' function turns a string containing a number and a currency code (EUR, USD) or symbol (€, $) back into its raw parts: the number value and the currency code. The results are returned in an array. Element Description $ A culture-specific currency symbol. Its position in the string is defined by the CurrencyNegativePattern and CurrencyPositivePattern properties of the NumberFormatInfo object returned by the GetFormat method of the provider parameter.

How about a CleanCurrency method?

/// 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);
  }
}

The idea here being to just get an actual number regardless of what the string content is.

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

NumberFormatter::parseCurrency - Manual, public NumberFormatter::parseCurrency ( string $value , string &$currency [, int Parse a string into a double and a currency using the current formatter. Dim value As String Dim number As Decimal ' Parse a floating-point value with a thousands separator. value = "1,643.57" If Decimal.TryParse(value, number) Then Console.WriteLine(number) Else Console.WriteLine("Unable to parse '{0}'.", value) End If ' Parse a floating-point value with a currency symbol and a ' thousands separator. value

I've expounded on Hari Prasad's answer. With this you can minimize the culture result. Update "SupportedCultures" with the ones you might use in your app.

    private static readonly List<string> SupportedCultures = new List<string> {"en-US", "en-GB", "fr-FR"};

    public static void Main()
    {
        var (amount, culture) = ParseCurrencyWithSymbol("$256.12");
        Console.WriteLine($"{culture?.Name} | {amount}");

        var (amount2, culture2) = ParseCurrencyWithSymbol("£389.17");
        Console.WriteLine($"{culture2?.Name} | {amount2}");

        var (amount3, culture3) = ParseCurrencyWithSymbol("€421,10");
        Console.WriteLine(culture3 != null ? $"{culture3.Name} | {amount3}" : "Failed!");
    }

    public static Tuple<decimal?, CultureInfo> ParseCurrencyWithSymbol(string input)
    {
        var culture = CultureInfo.GetCultures(CultureTypes.AllCultures)
            .Where(x => SupportedCultures.Contains(x.Name))
            .FirstOrDefault(c => input.Contains(c.NumberFormat.CurrencySymbol));

        if (culture == null) return new Tuple<decimal?, CultureInfo>(null, null);

        return new Tuple<decimal?, CultureInfo>(decimal.Parse(input,
            NumberStyles.Currency | NumberStyles.AllowCurrencySymbol |
            NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, culture), culture);
    }

NumberFormatInfo Class (System.Globalization), "en") continue; // Display the culture name and currency symbol. contains culture-specific information that is used when you format and parse numeric values. The symbols (such as the currency symbol, the group separator, the decimal separator, and the positive and negative signs) that can appear in the string to be parsed are defined by the members of the System.Globalization.NumberFormatInfo object that is passed either implicitly or explicitly to the Parse method.

dojo.currency (version 1.7), The currencies are specified by a three-letter international symbol in all uppercase, and returns String Builds the regular needed to parse a currency value� currency.js. A small, lightweight javascript library for working with currency values. Download currency.js. v2.0.2 (1.14 kB). Star Usage. currency.js was built to work around common floating point issues in javascript with a flexible api.

java.text.NumberFormat.getCurrencyInstance java code examples , How to parse a currency Amount (US or EU) to float value in Java. try { String How do I convert a string number value with a dollar sign to BigDecimal in java? currency value uses decimal notation; there are no digits in the string that are not a part of the currency value; currency value contains either 0 or 2 digits in its fractional part * The regexp can even handle something like "1,999 dollars and 99 cents", though it isn't an intended feature and it should not be relied upon. Hope this will help

Formatting Numbers, NumberFormat helps format and parse numbers for any locale. Currency formatting, i.e., the formatting of monetary values, combines a number with and whether the currency symbol or name is displayed before or after the number, while� I needed to parse a string that contains a currency symbol to decimal. You are converting a given decimal to string. So that's a different requirement. However, it is already answered. – Tim Schmelter Aug 29 '13 at 10:18

Comments
  • Move to another country (one that use $ as currency symbol and . as decimal separator) . Alternatively read on CultureInfo as it may be cheaper.
  • The currency string will be dynamic, not hard coded like my example. E.g. $2.10, €2,66, etc. How will I know the CultureInfo in advance?
  • Run away... There is no way to parse $3,100 correctly without knowledge of CultureInfo used to format the value. Checking against list of all currency symbols and hoping you've guessed decimal separator correctly is the safest bet (I'd not recommending to take that bet so).
  • With Euros, your code outputs 210, which is wrong, as in EU, the "comma" is the decimal separator, not the "period"
  • @l3utterfly ahh.. not noticed, thanks for pointing. Will fix it.
  • @l3utterfly fixed it.
  • Thanks, I used a very similar implementation based on your answer, though I didn't think to use AllCultures and group by currency symbol. Thanks!
  • Still not correct, if you have two same currency symbols, with different decimal point notation, you might use the incorrect notation. A Dutch citizen would write: € 4000,32, while a USA citizen would write € 4,000.32 if he is talking about investing money in the Netherlands
  • There really nothing that would help OP :) ... Especially this code as not every place put currency symbol in front.
  • @AlexeiLevenkov Yeah, I agree. The issue is too broad with too many uncertainties. Regards,
  • What about it? The idea here is "1,500" and "1.500" are very different values - there is no explanation how your code solves that (in addition to some very complicated implementation of Regex.Replace("$1.2", @"[^\d,\.]","") )