-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathparsing.jl
More file actions
154 lines (133 loc) · 4.13 KB
/
Copy pathparsing.jl
File metadata and controls
154 lines (133 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
num = raw"\d+\.?\d*" # x.xx decimal number
first = "([+-]?\\s?$num)" # leading digit is required, can have +- with 1 space
deg_delims = "[°d:\\s]" # only for dms
ha_delims = "[h:\\s]" # only for hms
min_delims = "['m:′\\s]" # shared
sec_delims = "[\"″s\\s]" # shared
dms_dirs = "(N|S)" # positive first
hms_dirs = "(E|W)" # positive first
# the trailing ()? groups are optional, so only leading digit is required
const dms_re = Regex("$first$deg_delims?($num)?$min_delims?($num)?$sec_delims?$dms_dirs?")
const hms_re = Regex("$first$ha_delims?($num)?$min_delims?($num)?$sec_delims?$hms_dirs?")
"""
parse_dms(input)
Parses a string input in "deg:arcmin:arcsec" format to the tuple `(degrees, arcminutes, arcseconds)`. The following delimiters will all work and can be mixed together (the last delimiter is optional):
```
"[+-]xx[°d: ]xx['′m: ]xx[\\\"″s][NS]"
```
if the direction ("N" or "S") is provided, "S" is considered negative (and "-1:0:0S" is 1 degree North)
"""
function parse_dms(input)
m = match(dms_re, strip(input))
m === nothing && error("Could not parse \"$input\" to sexagesimal")
deg = parse(Float64, filter(!isspace, m.captures[1]))
if m.captures[2] !== nothing
min = parse(Float64, m.captures[2])
else
min = 0.0
end
if m.captures[3] !== nothing
sec = parse(Float64, m.captures[3])
else
sec = 0.0
end
if m.captures[4] !== nothing
if m.captures[4] == "S"
deg = -deg
end
end
return deg, min, sec
end
"""
parse_hms(input)
Parses a string input in "ha:min:sec" format to the tuple `(hours, minutes, seconds)`. The following delimiters will all work and can be mixed together (the last delimiter is optional):
```
"[+-]xx[h ]xx['′m: ]xx[\\\"″s][EW]"
```
if the direction ("E" or "W") is provided, "W" is considered negative (and "-1:0:0W" is 1 degree East)
"""
function parse_hms(input)
m = match(hms_re, strip(input))
m === nothing && error("Could not parse \"$input\" to hour angles")
ha = parse(Float64, filter(!isspace, m.captures[1]))
if m.captures[2] !== nothing
min = parse(Float64, m.captures[2])
else
min = 0.0
end
if m.captures[3] !== nothing
sec = parse(Float64, m.captures[3])
else
sec = 0.0
end
if m.captures[4] !== nothing
if m.captures[4] == "W"
ha = -ha
end
end
return ha, min, sec
end
"""
@dms_str
Parse a string in "deg:arcmin:arcsec" format directly to an angle. By default, it will be parsed as radians, but the angle can be chosen by adding a flag to the end of the string
* dms"..."rad -> radians (default)
* dms"..."deg -> degrees
* dms"..."ha -> hour angles
# Examples
```jldoctest
julia> dms"12:17:25.3"
0.21450726764795752
julia> dms"12:17:25.3"rad # default
0.21450726764795752
julia> dms"12:17:25.3"deg
12.29036111111111
julia> dms"12:17:25.3"ha
0.8193574074074074
```
# See also
[`parse_dms`](@ref)
"""
macro dms_str(input, flag="rad")
if flag === "rad"
return dms2rad(input)
elseif flag === "deg"
return dms2deg(input)
elseif flag === "ha"
return dms2ha(input)
else
err = ArgumentError("angle type $flag not recognized. Choose between `deg`, `rad`, or `ha`")
return :(throw($err))
end
end
"""
@hms_str
Parse a string in "ha:min:sec" format directly to an angle. By default, it will be parsed as radians, but the angle can be chosen by adding a flag to the end of the string
* hms"..."rad -> radians (default)
* hms"..."deg -> degrees
* hms"..."ha -> hour angles
# Examples
```jldoctest
julia> hms"12:17:25.3"
3.2176090147193626
julia> hms"12:17:25.3"rad # default
3.2176090147193626
julia> hms"12:17:25.3"deg
184.35541666666666
julia> hms"12:17:25.3"ha
12.29036111111111
```
# See also
[`parse_hms`](@ref)
"""
macro hms_str(input, flag="rad")
if flag === "rad"
return hms2rad(input)
elseif flag === "deg"
return hms2deg(input)
elseif flag === "ha"
return hms2ha(input)
else
err = ArgumentError("angle type $flag not recognized. Choose between `deg`, `rad`, or `ha`")
return :(throw($err))
end
end