golang正则表达式提取数量和它们的单位对

时间:2014-01-05 05:55:04

标签: regex go

我有一组表示持续时间的人类可读字符串。以下是四个例子:

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>

1 个答案:

答案 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]);
}

Demo


旁注

以下字符串文字:

"(?P<quant>\\d+) (?P<unit>\\w+)+"

可以表示为以下原始字符串文字。

`(?P<quant>\d+) (?P<unit>\w+)+`

请参阅String literals