Reputation: 71
I'm trying to create a method that can handle and validate integers as on ok input. The issue is our requirements which states the following numbers as an ok input regardless of chosen language:
1500, 1.500, 1,500, 1 500
-1500, -1.500, -1,500, -1 500
1500000, 1.500.500, 1,500,500 1 500 500
-1500000, -1.500.500, -1,500,500 -1 500 500
and so on.
My method now looks like this:
private bool TryParseInteger(string controlValue, out int controlInt)
{
int number;
NumberStyles styles = NumberStyles.Integer | NumberStyles.AllowThousands;
bool result = Int32.TryParse(controlValue, styles,
CultureInfo.InvariantCulture, out number);
controlInt = number;
return result;
}
This does not work as I want it to. 1.500 and 1.500.500 is not validated as a correct input.
Is there another way to approach this?
Thanks for all the help. As it turns out 1.500,50 (and so on) should not pass validation which makes the suggested solutions not work. Any other ideas?
Upvotes: 7
Views: 839
Reputation: 495
I think the issue here is that 1.500
is understood differently per country. For instance, in the US that is equal to 1 and a half with some pointless zeroes where in Germany (I if memory serves) it is understood to be one thousand, five hundred.
In harmony with that, you should add a line at the beginning of the method like this:
controlValue = new string(controlValue.Where(c => !char.IsPunctuation(c) && c != ' ' || c == '-'));
This will remove all commas, periods and spaces which will work given that you only want integers. If you wanted to get a decimal, then we'd be in trouble...
Upvotes: 3
Reputation: 496
You can create your own custom culture, and alter the NumberGroupSeparator
as needed.
private static bool TryParseInteger(string controlValue, out int controlInt)
{
String[] groupSeparators = { ",", ".", " "};
CultureInfo customCulture = CultureInfo.InvariantCulture.Clone() as CultureInfo;
customCulture.NumberFormat.NumberDecimalSeparator = "SomeUnlikelyString";
NumberStyles styles = NumberStyles.Integer | NumberStyles.AllowThousands;
bool success = false;
controlInt = 0;
foreach (var separator in groupSeparators)
{
customCulture.NumberFormat.NumberGroupSeparator = separator;
success = Int32.TryParse(controlValue, styles, customCulture, out controlInt);
if (success)
{
break;
}
}
return success;
}
Upvotes: 0
Reputation: 1028
If you don't want to match 1,500.500
or 1.500,500
, you can replace all .
's to ,
's and try to parse it again. Something like this:
private bool TryParseInteger(string controlValue, out int controlInt)
{
int number;
NumberStyles styles = NumberStyles.Integer | NumberStyles.AllowThousands;
bool result = Int32.TryParse(controlValue, styles,
CultureInfo.InvariantCulture, out number);
if (!result)
{
controlValue = controlValue.Replace('.', ',');
result = Int32.TryParse(controlValue, styles,
CultureInfo.InvariantCulture, out number);
}
controlInt = number;
return result;
}
Upvotes: 3
Reputation: 9508
Just replace all those signs!
This code:
string[] arr = new[] { "1500", "1.500", "1,500", "1 500", "-1500", "-1.500", "-1,500", "-1 500",
"1500000", "1.500.500", "1,500,500","1 500 500",
"-1500000", "-1.500.500", "-1,500,500","-1 500 500"};
foreach (var s in arr)
{
int i = int.Parse(s.Replace(" ", "").Replace(",", "").Replace(".", ""));
Console.WriteLine(i);
}
Produces:
1500
1500
1500
1500
-1500
-1500
-1500
-1500
1500000
1500500
1500500
1500500
-1500000
-1500500
-1500500
-1500500
Upvotes: 3