0

I am looking for a regex that is capable of validating that a string contains any number from 0 upwards and also allows for a decimal point to be at any position other than something like .1 or .45. By the decimal being at any point I mean the number should be capable of having any number of precision places.

Numbers could really be anything:

1
2
3.5
3.58278723475
6523424.82347265

I have this which of course fails as my regex doesnt take decimal points into account:

 foreach (string[] coorPairArray in extents.Select(t => t.Trim().Split(' ')))
 {
     Regex isnumber = new Regex("^[0-9]+$");

     if ((!isnumber.IsMatch(coorPairArray[0]) || (!isnumber.IsMatch(coorPairArray[1]))))
     {
         dataBaseConnection.Close();

         throw new ArgumentException("Error: An extent value contained alphanumeric data. GetExtentsAsGml().");
     }
  }
CSharpened
  • 11,674
  • 14
  • 52
  • 86
  • 1
    Minor point: I would move the "isNumber" initialisation outside the foreach loop (or even to a static field): no need to re-initialize it on every run through the loop. Saves a few microseconds :-) – Hans Kesting Jul 30 '12 at 10:12

5 Answers5

4

This should do the work:

 Regex isnumber = new Regex(@"^[0-9]+(\.[0-9]+)?$");
M. Mennan Kara
  • 10,072
  • 2
  • 35
  • 39
3

Do you even need a regex for this? Wouldn't something like this work:

foreach (string[] coorPairArray in extents.Select(t => t.Trim().Split(' '))) 
{
    var lat = Decimal.MinValue;
    var lng = Decimal.MinValue;
    if (!Decimal.TryParse(coorPairArray[0], out lat) || !Decimal.TryParse(coorPairArray[1], out lng))
    {
         dataBaseConnection.Close(); 
         throw new ArgumentException("Error: An extent value contained alphanumeric data. GetExtentsAsGml().");
    }

    // do something with lat/lng
} 
James
  • 80,725
  • 18
  • 167
  • 237
1
[1-9][0-9]*(\.[0-9]+)? | 0\.[0-9]+

First one is for normal numbers. Second one to handle things like 0.1

Of course add ^ and $ as required.

I would rather go with James' answer instead of this. it is only for curiosity.

Fakrudeen
  • 5,778
  • 7
  • 44
  • 70
1

Better to do a tryparse as in @James answer, if you want to go throught the regex then here is a sample :

[Test]
[TestCase("1")]
[TestCase("2")]
[TestCase("3.5")]
[TestCase("3.58278723475")]
[TestCase("6523424.82347265")]
public void FluentCalculator_Test(string testSource)
{
    var match = Regex.Match(testSource, @"^(?:[-+]?[1-9]\d*|0)?(?:\.\d+)?$");
    Assert.IsTrue(match.Success);
}
Giorgio Minardi
  • 2,765
  • 1
  • 15
  • 11
  • Can you tell me why it is better to do the tryParse rather than the regex? In my code the try parse doesnt really fit in well so I will stick with the regex for now but what are the reasons for favouring a tryparse? +1 for the useful unit test btw :) – CSharpened Jul 30 '12 at 10:21
  • 2
    @CSharpened `TryParse` is built into the Framework therefore will not break in future versions of .NET (unless of course they change the `TryParse` method which is highly unlikely). Also IMO you are sort of misusing regex in this scenario. Your not trying to *match* data, your trying to validate it so actually try parse is a *better fit*. If your worried about what the code looks like then why not just introduce a helper method e.g. `ValidateCoordinates` and then you abstract the validation logic which gives you the flexibility of changing it without affecting your business logic. – James Jul 30 '12 at 10:25
  • Thats actually a very good idea and some good reasons too James. Thanks. In terms of the actual regex I will have to keep Mennans answer as the correct one as it answered my question. Thinking about it now though I will abstract out the functionality as you mentioned. Dont know why I didnt think about that as I have done similar elsewhere in the solution. – CSharpened Jul 30 '12 at 10:32
  • Also, here you can find some info about regex vs tryparse http://stackoverflow.com/questions/5715200/regex-vs-tryparse-what-is-the-best-in-performance – Giorgio Minardi Jul 30 '12 at 10:37
0

this works with me fine

    @"^\d*(?:\.\d+)?$"
Sara
  • 86
  • 2
  • 11