Python Forum

Full Version: [SOLVED] Can't figure out right regex
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

I need to convert GPS coordinates from DMS to DD.

Provided there's no even better way, what's the right regex to 1) find the orientation (N, S, W, E) and 2) keep in memory using brackets?

Thank you.

#From Degrees, minutes, and seconds (DMS) to Decimal degrees (DD)

import re

coords = "45° 46' 52\" N 108° 30' 14\" W"

coords = coords.replace(" ","") #remove spaces -> 45°46'52"N108°30'14"W

coords = re.match(r"(\d+)°(\d+)'(.+?)\"([NSWE])",coords)
coords = re.match(r"(\d+)°(\d+)'(.+?)\"[(NSWE)]",coords)
coords = re.match(r"(\d+)°(\d+)'(.+?)\"([NSWE].)",coords)
coords = re.match(r"(\d+)°(\d+)'(.+?)\"[(NSWE).]",coords)
if coords:
	#OK print(f"{coords.group(0)},{coords.group(1)},{coords.group(2)},{coords.group(3)}")

	#4: IndexError: no such group
	print(f"{coords.group(1)},{coords.group(2)},{coords.group(3)},{coords.group(4)}")
Something like this extract the necessary components (degrees, minutes, seconds, and orientation).
Convert the extracted components to decimal degrees.
import re

def dms_to_dd(degrees, minutes, seconds, direction):
    dd = float(degrees) + float(minutes)/60 + float(seconds)/3600
    if direction in ['S', 'W']:
        dd *= -1
    return dd

coords = "45° 46' 52\" N 108° 30' 14\" W"
coords = coords.replace(" ", "")
# Regex pattern to match DMS coordinates
pattern = r"(\d+)°(\d+)'(\d+)\"([NSWE])"
matches = re.findall(pattern, coords)
if matches:
    lat_dms = matches[0]
    lon_dms = matches[1]
    lat_dd = dms_to_dd(*lat_dms)
    lon_dd = dms_to_dd(*lon_dms)
    print(f"Latitude (DD): {lat_dd}")
    print(f"Longitude (DD): {lon_dd}")
else:
    print("No valid DMS coordinates found.")
Output:
Latitude (DD): 45.78111111111111 Longitude (DD): -108.5038888888889
Maybe like this:

import regex
 
coords = '45° 46\' 52" N 108° 30\' 14" W'
# simple it up a bit, all those backstrokes are confusing
string = coords.replace('°', ' degrees').replace('\'', ' minutes').replace('"', ' seconds') 
# regex for string 
e = regex.compile(r'(\d+)\s+degrees\s+(\d+)\s+minutes\s+(\d+)\s+seconds\s+([NSWE])\s+(\d+)\s+degrees\s+(\d+)\s+minutes\s+(\d+)\s+seconds\s+([NSWE])') 
# find what you want
res = e.match(string)
for e in res.groups():
    print(e)
Output:
45 46 52 N 108 30 14 W
I believe you can do the arithmetic.
Turns out the regex was correct, but I was confused between () and [] to access the hits.

And unlike findall(), match() starts from the beginning of the string, and only returns the first occurence.

Thanks.