11

When I search for validate latitude longitude [javascript], I get answers that match digits indiscriminately or match the wrong range or are just too complicated to debug.

In fairness, some of these OPs did ask for regexes, and Javascript isn't my first language, but it seems like it would be more straightforward and less error-prone just to do the math:

function isLatitude(maybeLat) {
  var latF = parseFloat(maybeLat)
  if (isNaN(latF)) return false
  return (latF >= -90 && latF <= 90)
}

function isLongitude(maybeLon) {
  var lonF = parseFloat(maybeLon)
  if (isNaN(lonF)) return false
  return lonF >= -180 && lonF <= 180
}

Yes, it's less terse, but it's a lot more readable than

^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$

Is there some advantage to using regular expressions? Performance? Browser compatibility? Library tools that only allow regex validation? SO users showing off their mad regex sk1llz?

Community
  • 1
  • 1
David Moles
  • 48,006
  • 27
  • 136
  • 235
  • No reason to use regex, although `parseFloat` will allow what would be a malformed lat/lng (e.g., `parseFloat('12a')` will return `12`. That may be what you want. Using `isFinite` and `Math.abs` will reject those. – Dave Newton Oct 03 '16 at 23:44
  • 2
    Probably because there are several ways of denoting lat/lng, For instance DD MM.MMM (Degrees, Minutes, decimal minutes), DD.DDDD (Degrees, decimal degrees), DD MM SS (Degree, Minutes, Seconds) etc. So it maybe that they are trying to catch as many possible formats as possible – Patrick Evans Oct 03 '16 at 23:47
  • @PatrickEvans Ah. I totally forgot about that; but it's obvious--good thing you brought that up. – Dave Newton Oct 03 '16 at 23:48
  • @PatrickEvans Can you make that an answer? – David Moles Oct 04 '16 at 16:49
  • @DaveNewton Thanks for that -- I'd forgotten JavaScript didn't require explicit conversion of strings to numbers. – David Moles Oct 04 '16 at 16:50

2 Answers2

25

I absolutely think this is overkill / unnecessary use of a regex. I think your approach is correct, though it can be shortened somewhat:

function isLatitude(lat) {
  return isFinite(lat) && Math.abs(lat) <= 90;
}

function isLongitude(lng) {
  return isFinite(lng) && Math.abs(lng) <= 180;
}

isFinite will reject anything that isn't a (finite) number, or can't be automatically converted to a number (like a string containing a number). Also, I've taken to using lng to represent longitude since it's the same length as lat, and can't be confused with a keyword.

The Math library functions (and isFinite) will automatically coerce strings to numbers, if possible.

Ethan Brown
  • 26,892
  • 4
  • 80
  • 92
  • Can you add a note to the answer pointing out for the JavaScript-inexperienced that the strings don't need to be converted to numbers before being passed to the math functions? – David Moles Oct 04 '16 at 16:49
  • 1
    Done, @DavidMoles – Ethan Brown Oct 05 '16 at 05:44
  • It's returning true if lat is an empty string. I had return lat != "" && isFinite(lat) && Math.abs(lat) <= 90; to correct the problem – Patrick Nov 03 '17 at 09:52
  • Hi, Patrick, you're correct about empty / whitespace-only strings -- annoyingly, JavaScript converts such strings to the number 0. To be _really_ sure, you would probably want to add `(typeof lat !== 'string' || lat.trim() !== '')` but what a pain. Some days it makes you want a typed language. It works fine for me for "-.629218"....? – Ethan Brown Nov 03 '17 at 20:59
  • @EthanBrown No idea how stable it is, but loos good to me. I hope it will not create in production where I have thousands of users. – Saeed Afzal Dec 19 '18 at 19:25
1

One reason to use a regex may be to perform as-you-type partial string validation so as to prevent entry of an invalid value in the fist place, instead of catching an invalid final result after the user hits some submit button or key.

I suppose you could just try to coerce the string to a number and compare after each keystroke, but how does it deal with conversion of "-" and "." - I don't remember - its been many years since I cared about Javascript. The FSM of a compiled regex will be more efficient than this conversion process but it would be insignificant in this case.

Dave
  • 764
  • 7
  • 17