I have a set of human readable strings expressing a duration of time. Here are four examples:
1 days 40 hrs 23 min 50 sec
3 hrs 1 min 30 sec
10 days 23 min 11 sec
52 sec
I am trying to convert these strings into number of seconds. The math to do this is quite simple once the string is broken down into its components - it's just multiplication and addition. I am having some issues however with writing the regular expression to parse the string into [<quantity>, <unit>]
pairs. As an example, the output I would like for the string:
1 days 40 hrs 23 min 50 sec
is an array (or slice) like:
[[1, "days"], [40, "hrs"], [23, "min"], [50, "sec"]]
.
Below is the code for what I've tried so far and its output (executable at http://play.golang.org/p/iR-xfc8MVQ). segs
was my first attempt, which seems to break the string down into 4 components ok but each component is just a string like 1 days
rather than a 2-element array like [1, days]
. segs2
was my second attempt, which seems to do something weirder where each component is repeated twice.
// time unit tokenizer
package main
import "fmt"
import "regexp"
func main() {
s := "1 days 40 hrs 23 min 50 sec"
re := regexp.MustCompile("(?P<quant>\\d+) (?P<unit>\\w+)+")
segs := re.FindAllString(s, -1)
fmt.Println("segs:", segs)
fmt.Println(segs[0], "," ,segs[1], ",", segs[2], ",", segs[3])
fmt.Println("length segs:", len(segs))
segs2 := re.FindAllStringSubmatch(s, -1)
fmt.Println("segs2:", segs2)
fmt.Println(segs2[0], "," ,segs2[1], ",", segs2[2], ",", segs2[3])
fmt.Println("length segs2:", len(segs2))
}
Output:
segs: [1 days 40 hrs 23 min 50 sec]
1 days , 40 hrs , 23 min , 50 sec
length segs: 4
segs2: [[1 days 1 days] [40 hrs 40 hrs] [23 min 23 min] [50 sec 50 sec]]
[1 days 1 days] , [40 hrs 40 hrs] , [23 min 23 min] , [50 sec 50 sec]
length segs2: 4
I've written a similar regex is Python which works OK, so I'm really not sure whether I am doing something incorrect for Go's regular expression syntax or perhaps making the wrong call on the re
object.