Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Degrees, Minutes and seconds regex

Tags:

regex

I need validate with RegEx an sexagecimal value, for example: 24° 12' 55,4" or 32° 24' 15,4".

For now, I have the next RegEx, that matches successful with degrees and minutes:

^([0-8][0-9]|[9][0])°\s([0-4][0-9]|[5][9])'$

But, when add the seconds validator have problems:

^([0-8][0-9]|[9][0])°\s([0-4][0-9]|[5][9])'\s([0-4][0-9]|[5][9],[0-9])''$

I'm new with RegEx, any ideas?

like image 708
ramiromd Avatar asked Aug 19 '13 19:08

ramiromd


4 Answers

This is an improvement of @OmnipotentEntity regex.

Features:

  • Negative angle match
  • Stop match at (+/-)360° (so it doesn't match something like 360° 7' 24", but only 360°)
  • Match separately degrees (max 360°), minutes (max 59) and seconds (max 59.9")
  • Match integer for degrees, and minutes, but float (1 digit precision) for seconds

Be aware that it accepts only point decimal separator (.) for seconds. Change this depending on your needs.

Angle degrees, minutes and seconds regex:

/^(?:(-?360(*ACCEPT))|(-?[1-3]?[0-9]?[0-9]?))°?\s?([0-5]?[0-9])?\'?\s?([0-5]?[0-9](?:.{1}[0-9])?)?"?$/

That's a link to a regex playground to try what's the limit of this expression.

like image 77
Marco Consiglio Avatar answered Oct 23 '22 18:10

Marco Consiglio


First off, you have some redundancy:

^([0-8][0-9]|[9][0])°\s([0-4][0-9]|[5][9])'$

can become just:

^([0-8][0-9]|90)°\s([0-4][0-9]|59)'$

Next you have a logical issue, in your second match, you're matching 0-4 then 0-9 (ie 00-49) and then matching just 59. You can change this to:

^([0-8][0-9]|90)°\s[0-5][0-9]'$

to match 00-59

Next let's look at your seconds modification:

\s([0-4][0-9]|[5][9],[0-9])''$

Same issue as before, except now you've added a decimal, but not to both sides of the | so it will only match on one side, if we fix this like we fixed the last one we get:

^([0-8][0-9]|90)°\s[0-5][0-9]'\s[0-5][0-9],[0-9]''$

Next you have two single quotes instead of a double quote, so fix that:

^([0-8][0-9]|90)°\s([0-5][0-9])'\s[0-5][0-9],[0-9]"$

Now we need to ask ourselves, is the first digit on this mandatory? Probably not. So mark it as potentially missing using a ?

^([0-8]?[0-9]|90)°\s[0-5]?[0-9]'\s[0-5]?[0-9],[0-9]"$

Next, is the fractional part of the second mandatory? Probably not, so mark it as potentially missing:

^([0-8]?[0-9]|90)°\s[0-5]?[0-9]'\s[0-5]?[0-9](,[0-9])?"$

Finally, I'm assuming that each part except for the degrees is not required, mark them as potentially missing:

^([0-8]?[0-9]|90)°(\s[0-5]?[0-9]')?(\s[0-5]?[0-9](,[0-9])?")?$

There's other things you can do to make this better. But, this should get you started.

like image 42
OmnipotentEntity Avatar answered Nov 13 '22 08:11

OmnipotentEntity


I've recently had a similar use case but had to match variations such as

14° 58' 40.068" E
36°57'9" N

so I came up with

(\d+)\s?\°\s?(\d+)\s?\'\s?(\d{1,}\.?\,?\d{0,}?)\"\s?(N|W|S|E)

Testable here.

like image 21
Joe - Elasticsearch Handbook Avatar answered Nov 13 '22 10:11

Joe - Elasticsearch Handbook


I needed a far more robust solution for an open-source project, qalGeohash-TSQL, than has been provided in both the answers and comments on this question.

After two hours of playing with solutions within this fantastic online Regex exploration resource, I finally have exactly what I needed; a precisely limited domain for each of both longitude (x-axis) and latitude (y-axis).

Longitude Solution:

  • URL At Which to Explore/Experiment (includes test cases): https://regexr.com/5lcpk
  • RegEx: ^((180[°|\s]\s*)(0{1,2}['|\s]\s*)(0{1,2}([.|,]0{1,20})?["|\s]\s*)|((1[0-7]\d|\d\d|\d)[°|\s]\s*)(([0-5]\d|\d)['|\s]\s*)(([0-5]\d|\d)([.|,]\d{1,20})?["|\s]\s*))[EWew]$

Latitude Solution:

  • URL At Which to Explore/Experiment (includes test cases): https://regexr.com/5lcq9
  • RegEx: ^((90[°|\s]\s*)(0{1,2}['|\s]\s*)(0{1,2}([.|,]0{1,20})?["|\s]\s*)|(([1-8]\d|\d)[°|\s]\s*)(([0-5]\d|\d)['|\s]\s*)(([0-5]\d|\d)([.|,]\d{1,20})?["|\s]\s*))[NSns]$

Below is a breakdown of the components which compose the above solutions:

Longitude Components:

  • At 180:
    • Degrees: (180[°|\s]\s*)
    • Minutes: (0{1,2}['|\s]\s*)
    • Seconds: (0{1,2}([.|,]0{1,20})?["|\s]\s*)
  • Below 180:
    • Degrees: ((1[0-7]\d|\d\d|\d)[°|\s]\s*)
    • Minutes: (([0-5]\d|\d)['|\s]\s*)
    • Seconds: (([0-5]\d|\d)([.|,]\d{1,20})?["|\s]\s*)
  • Directional: [EWew]

Latitude Components:

  • At 90:
    • Degrees: (90[°|\s]\s*)
    • Minutes: (0{1,2}['|\s]\s*)
    • Seconds: (0{1,2}([.|,]0{1,20})?["|\s]\s*)
  • Below 90:
    • Degrees: (([1-8]\d|\d)[°|\s]\s*)
    • Minutes: (([0-5]\d|\d)['|\s]\s*)
    • Seconds: (([0-5]\d|\d)([.|,]\d{1,20})?["|\s]\s*)
  • Directional: [NSns]
like image 1
chaotic3quilibrium Avatar answered Nov 13 '22 10:11

chaotic3quilibrium