Regular Expression to parse a currency with any symbol

G

Guest

Hello,

I need a regular expression to match a currency with its symbol, for example
Pound66.99 must return 66.99 or Pound(66.99) or Pound-66.99 or -66.99Pound
return -66.99 or any other combination return the decimal number.

I have created a regular expression, but it seems that it does not work if
the number is Pound66.99 but it works if the sign is after the number:

public static Decimal ConvertToDecimal(String str)
{
String pattern = @"^\(?-?[\d]*[,]*[\d]*\.?[\d]*\)?";
System.Text.RegularExpressions.Match match
=System.Text.RegularExpressions.Regex.Match(str, pattern);
if (match.Success)
{
decimal result;
//try to parse to decimal normally
if (decimal.TryParse(match.Groups[0].ToString(),
System.Globalization.NumberStyles.Any, null, out result))
return result;
}
return 0;
}--
Mike
 
J

Jesse Houwing

Hey Mike,

Your regex matches a lot more than you're actually trying to find. The
following should be more in the general direction you're trying to find:

@"\(\d{1,3}(?:,\d{3})*(?:\.\d+)?\)|-?\d{1,3}(?:,\d{3})*(?:\.\d+)?";

Do keep in mind that \d*,*\d*\.?\d* will match
234234,,,,,,,,,91872391279379123791827392173912379172398.82163816238716238
as well, which is probably not what you're looking for. If you want to
allow any format that is using either the thousand separator or not you
could also use this:

@"\(\d{1,3}(?:,?\d{3})*(?:\.\d+)?\)|-?\d{1,3}(?:,?\d{3})*(?:\.\d+)?";

Also notice that I basically check for the () notation and then for the
- notation. Your regex would also have found:

(-99 or -99)

Jesse Houwing
 
J

John B

Mike9900 said:
Hello,

I need a regular expression to match a currency with its symbol, for example
Pound66.99 must return 66.99 or Pound(66.99) or Pound-66.99 or -66.99Pound
return -66.99 or any other combination return the decimal number.

I have created a regular expression, but it seems that it does not work if
the number is Pound66.99 but it works if the sign is after the number:

public static Decimal ConvertToDecimal(String str)
{
String pattern = @"^\(?-?[\d]*[,]*[\d]*\.?[\d]*\)?";
System.Text.RegularExpressions.Match match
=System.Text.RegularExpressions.Regex.Match(str, pattern);
if (match.Success)
{
decimal result;
//try to parse to decimal normally
if (decimal.TryParse(match.Groups[0].ToString(),
System.Globalization.NumberStyles.Any, null, out result))
return result;
}
return 0;
}--
Mike

Or a totally different solution:

if(currencyString.IndexOf("poundSign") != -1)
{
currencyString = currencyString.Replace("poundSign", "");
}
....tryparse as before
 
G

Guest

This does not work, because I do not know the currency symbol. It could be
franc ro any other, such as FR-888.22.
--
Mike


John B said:
Mike9900 said:
Hello,

I need a regular expression to match a currency with its symbol, for example
Pound66.99 must return 66.99 or Pound(66.99) or Pound-66.99 or -66.99Pound
return -66.99 or any other combination return the decimal number.

I have created a regular expression, but it seems that it does not work if
the number is Pound66.99 but it works if the sign is after the number:

public static Decimal ConvertToDecimal(String str)
{
String pattern = @"^\(?-?[\d]*[,]*[\d]*\.?[\d]*\)?";
System.Text.RegularExpressions.Match match
=System.Text.RegularExpressions.Regex.Match(str, pattern);
if (match.Success)
{
decimal result;
//try to parse to decimal normally
if (decimal.TryParse(match.Groups[0].ToString(),
System.Globalization.NumberStyles.Any, null, out result))
return result;
}
return 0;
}--
Mike

Or a totally different solution:

if(currencyString.IndexOf("poundSign") != -1)
{
currencyString = currencyString.Replace("poundSign", "");
}
....tryparse as before
 
G

Guest

Thanks for the help.

This does not work for some numbers, for example if the number is E.999 it
return 999, if the number is e999,323,22.98 it returns 999323.

Please note that I use Decimal.parse with
System.Globalization.NumberStyles.Any afterward, so the most important thing
is that it strips symbol and gives the correct number.

Or should I use the normal loop and strip symbols?
--
Mike


Jesse Houwing said:
Hey Mike,

Your regex matches a lot more than you're actually trying to find. The
following should be more in the general direction you're trying to find:

@"\(\d{1,3}(?:,\d{3})*(?:\.\d+)?\)|-?\d{1,3}(?:,\d{3})*(?:\.\d+)?";

Do keep in mind that \d*,*\d*\.?\d* will match
234234,,,,,,,,,91872391279379123791827392173912379172398.82163816238716238
as well, which is probably not what you're looking for. If you want to
allow any format that is using either the thousand separator or not you
could also use this:

@"\(\d{1,3}(?:,?\d{3})*(?:\.\d+)?\)|-?\d{1,3}(?:,?\d{3})*(?:\.\d+)?";

Also notice that I basically check for the () notation and then for the
- notation. Your regex would also have found:

(-99 or -99)

Jesse Houwing
Hello,

I need a regular expression to match a currency with its symbol, for example
Pound66.99 must return 66.99 or Pound(66.99) or Pound-66.99 or -66.99Pound
return -66.99 or any other combination return the decimal number.

I have created a regular expression, but it seems that it does not work if
the number is Pound66.99 but it works if the sign is after the number:

public static Decimal ConvertToDecimal(String str)
{
String pattern = @"^\(?-?[\d]*[,]*[\d]*\.?[\d]*\)?";
System.Text.RegularExpressions.Match match
=System.Text.RegularExpressions.Regex.Match(str, pattern);
if (match.Success)
{
decimal result;
//try to parse to decimal normally
if (decimal.TryParse(match.Groups[0].ToString(),
System.Globalization.NumberStyles.Any, null, out result))
return result;
}
return 0;
}--
Mike
 
J

Jesse Houwing

Mike9900 said:
Thanks for the help.

This does not work for some numbers, for example if the number is E.999 it
return 999, if the number is e999,323,22.98 it returns 999323.

Yeah I made the expression quite strict the option with no digits before
the '.' wasn't in your sample data and 999,333,22 is syntactically
incorrect as the last part should contain 3 digits. These changes would
be quite simple to implement however:


\((?:\d{1,3}(?:,?\d+)*(?:\.\d+)?|\.\d+)\)|-?(?:\d{1,3}(?:,?\d+)*(?:\.\d+)?|\.\d+)


would probably catch these aswell.

Jesse
 
L

Larry Lard

Mike9900 said:
John B said:
Mike9900 said:
Hello,

I need a regular expression to match a currency with its symbol, for example
Pound66.99 must return 66.99 or Pound(66.99) or Pound-66.99 or -66.99Pound
return -66.99 or any other combination return the decimal number.

I have created a regular expression, but it seems that it does not work if
the number is Pound66.99 but it works if the sign is after the number:

public static Decimal ConvertToDecimal(String str)
{
String pattern = @"^\(?-?[\d]*[,]*[\d]*\.?[\d]*\)?";
System.Text.RegularExpressions.Match match
=System.Text.RegularExpressions.Regex.Match(str, pattern);
if (match.Success)
{
decimal result;
//try to parse to decimal normally
if (decimal.TryParse(match.Groups[0].ToString(),
System.Globalization.NumberStyles.Any, null, out result))
return result;
}
return 0;
}--
Mike

Or a totally different solution:

if(currencyString.IndexOf("poundSign") != -1)
{
currencyString = currencyString.Replace("poundSign", "");
}
....tryparse as before
This does not work, because I do not know the currency symbol. It could be
franc ro any other, such as FR-888.22.

So the best thing to do is assume the currency symbol could in fact be
anything at all, since storing a list of all known currencies would be
silly. So do this:

- remove all characters that aren't digits, sign characters, decimal
points.
- look for a sign character, and note it and remove it if found
- parse what remains as a number
- apply the sign

Regex is inappropriate when you know so little about the format of your
input.
 
G

Guest

This is another way, thanks. But it is possible to use regular expression.
Please see the message.
--
Mike


Larry Lard said:
John B said:
Mike9900 wrote:
Hello,

I need a regular expression to match a currency with its symbol, for example
Pound66.99 must return 66.99 or Pound(66.99) or Pound-66.99 or -66.99Pound
return -66.99 or any other combination return the decimal number.

I have created a regular expression, but it seems that it does not work if
the number is Pound66.99 but it works if the sign is after the number:

public static Decimal ConvertToDecimal(String str)
{
String pattern = @"^\(?-?[\d]*[,]*[\d]*\.?[\d]*\)?";
System.Text.RegularExpressions.Match match
=System.Text.RegularExpressions.Regex.Match(str, pattern);
if (match.Success)
{
decimal result;
//try to parse to decimal normally
if (decimal.TryParse(match.Groups[0].ToString(),
System.Globalization.NumberStyles.Any, null, out result))
return result;
}
return 0;
}--
Mike

Or a totally different solution:

if(currencyString.IndexOf("poundSign") != -1)
{
currencyString = currencyString.Replace("poundSign", "");
}
....tryparse as before
This does not work, because I do not know the currency symbol. It could be
franc ro any other, such as FR-888.22.

So the best thing to do is assume the currency symbol could in fact be
anything at all, since storing a list of all known currencies would be
silly. So do this:

- remove all characters that aren't digits, sign characters, decimal
points.
- look for a sign character, and note it and remove it if found
- parse what remains as a number
- apply the sign

Regex is inappropriate when you know so little about the format of your
input.

--
Larry Lard
Replies to group please
When starting a new topic, please mention which version of VB/C# you
are using
 
J

Jesse Houwing

Mike9900 said:
This is another way, thanks. But it is possible to use regular expression.
Please see the message.

Larry was completely correct that without specs you won't get it done
using regular expressions, but after we had the specs clear, it was no
issue :)

Jesse
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top