Reputation: 7230
I have a WPF application with a textbox where my user will enter a latitude value in decimal degrees (with up to 7 digits of precision). Valid latitudes range from -90.0000000 to 90.0000000, of course. I'm trying to create a regex to restrict input via the PreviewTextInput event for the textbox similar to this:
private void latitudeTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = !ValidateDecimalString(e.Text);
}
public static bool ValidateDecimalString(string decimalString)
{
Regex regex = new Regex("[^0-9]+");
return !regex.IsMatch(decimalString);
}
My current regex allows only numbers to be entered but there are some other limitations that I need to enforce as well like:
Examples of valid latitude values:
Can I achieve these additional restrictions just by modifying my regex? If so, how? Thanks!
Upvotes: 4
Views: 1937
Reputation: 45
another way (example with double) - not regex solution but works
bool IsDigitsOnlyLatitudaLongituda(string str, int deg)
{
// deg with value 0 is latitude, deg with value 1 is longitude
bool provjera = true;
int brojactocki = 0;
if (str.Length > 0)
{
if (str[0] == '.')
{
provjera = false;
}
if (str[str.Length - 1] == '.')
{
provjera = false;
}
}
var brojac = 0;
foreach (char c in str)
{
brojac = brojac + 1;
if (brojac != 1)
{
if (c == '-')
{
provjera = false;
}
}
if (c == '.')
{
brojactocki = brojactocki + 1;
}
}
if (brojactocki > 1)
{
provjera = false;
}
foreach (char c in str)
{
if ((c < '0' || c > '9') && (c != '.') && (c != '-'))
{
provjera = false;
}
}
double dblString;
if (deg == 0)
{
if (provjera == true)
{
dblString = Convert.ToDouble(str.Replace(".", ","));
if (dblString >= 90 || dblString <= -90)
{
provjera = false;
}
}
}
if (deg == 1)
{
if (provjera == true)
{
dblString = Convert.ToDouble(str.Replace(".", ","));
if (dblString >= 180 || dblString <= -180)
{
provjera = false;
}
}
}
return provjera;
}
Upvotes: 0
Reputation:
Lots of options for this. One way -
# @"^-?(?:(?:[0-9]|[1-8][0-9])(?:\.[0-9]{1,7})?|90(?:\.0{1,7})?)$"
^
-?
(?:
(?:
[0-9]
| [1-8] [0-9]
)
(?: \. [0-9]{1,7} )?
|
90
(?: \. 0{1,7} )?
)
$
Matching giant edge case
# @"^-?(?:(?:[0-9]|[1-8](?:[0-9]|$))(?:\.(?:[0-9]{1,7}|$))?|9(?:0|$)(?:\.(?:0{1,7}|$))?)?$"
^
-?
(?:
(?:
[0-9]
| [1-8] (?: [0-9] | $ )
)
(?:
\. (?: [0-9]{1,7} | $ )
)?
|
9 (?: 0 | $ )
(?:
\. (?: 0{1,7} | $ )
)?
)?
$
Upvotes: 1
Reputation: 13381
try something like this
public static bool ValidateDecimalString(string decimalString)
{
Regex regex = new Regex(@"^(-)?([0-9]+)(\.[0-9]+)?$");
return regex.IsMatch(decimalString);
}
for validate range better use converted value like
public static bool ValidateLatitudeString(string decimalString)
{
if(ValidateDecimalString(decimalString)){
double lat = 0;
return double.TryParse(decimalString, out lat) && lat<=90.0 && lat>=-90;
}
return false;
}
so possibly better will be without regex like
public static bool ValidateLatitudeString(string decimalString)
{
double lat = 0;
return double.TryParse(decimalString, out lat) && lat<=90.0 && lat>=-90;
}
Upvotes: 2
Reputation: 5317
How about this?
public static bool ValidateDecimalString(string decimalString)
{
Regex regex = new Regex("^-?([0-9]|[1-8][0-9]|90)([.][0-9]*)?$");
return regex.IsMatch(decimalString);
}
This will allow an optional leading hyphen-minus, followed by a number from 0 to 90 inclusive (but not 999 or 01), followed by optionally a decimal component. It will allow 90.1
though; to forbid this use:
public static bool ValidateDecimalString(string decimalString)
{
Regex regex = new Regex("^-?(([0-9]|[1-8][0-9])([.][0-9]*)?|90([.]0*))$");
return regex.IsMatch(decimalString);
}
This will allow 90.0
but not 90.1
.
Upvotes: 1
Reputation: 2085
While your question is how do I validate latitude with regex it seems like a better approach would be to use something like Decimal.TryParse.
public static bool ValidateLatitudeString(string decimalString)
{
decimal validLatitude;
if (decimal.TryParse(decimalString, out validLatitude))
{
if (validLatitude >= -90.0M && validLatitude <= 90.0M)
{
return true;
}
}
return false;
}
Upvotes: 1