我有一组表示持续时间的人类可读字符串。以下是四个例子:
1 days 40 hrs 23 min 50 sec
3 hrs 1 min 30 sec
10 days 23 min 11 sec
52 sec
我正在尝试将这些字符串转换为秒数。一旦将字符串分解为其组件,这样做的计算非常简单 - 它只是乘法和加法。我有一些问题,但编写正则表达式将字符串解析为[<quantity>, <unit>]
对。作为一个例子,我希望输出字符串的输出:
1 days 40 hrs 23 min 50 sec
是一个数组(或切片),如:
[[1, "days"], [40, "hrs"], [23, "min"], [50, "sec"]]
。
下面是我迄今为止尝试过的代码及其输出(可在http://play.golang.org/p/iR-xfc8MVQ处执行)。 segs
是我的第一次尝试,它似乎将字符串分解为4个组件,但是每个组件只是一个类似1 days
的字符串,而不是像[1, days]
这样的2元素数组。 segs2
是我的第二次尝试,它似乎做了一些奇怪的事情,每个组件重复两次。
// 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))
}
输出:
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
我写了一个类似的正则表达式是Python工作正常,所以我真的不确定我是否对Go的正则表达式语法做了不正确的事情,或者对re
对象进行了错误的调用。< / p>
答案 0 :(得分:8)
Regexp.FindAllStringSubmatch
返回[][]string
。但它的内容与Python函数re.findall
的返回值略有不同(我假设您在Python中使用了re.findall
。)
return_value[i][0]
包含完整匹配的字符串。 return_value[i][1]
包含已捕获的第1组。return_value[i][2]
包含已捕获的群组2. .... 打印return_value[i]
会导致return_value[i]
中的所有项目被打印。 (return_value[i][0]
,return_value[i][1]
,return_value[i][2]
,..)
您只需打印已捕获的群组匹配项([0]
除外)即可获得预期效果,如下所示:
segs2 := re.FindAllStringSubmatch(s, -1)
for i := 0; i < len(segs2); i++ {
fmt.Println(segs2[i][1], "," ,segs2[i][2]);
}
旁注
以下字符串文字:
"(?P<quant>\\d+) (?P<unit>\\w+)+"
可以表示为以下原始字符串文字。
`(?P<quant>\d+) (?P<unit>\w+)+`