2014-01-05 30 views
3

我有一組表示持續時間的人類可讀字符串。這裏有四個例子:golang正則表達式提取數量對及其單位

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對象的錯誤調用。

回答

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],...

segs2 := re.FindAllStringSubmatch(s, -1) 
for i := 0; i < len(segs2); i++ { 
    fmt.Println(segs2[i][1], "," ,segs2[i][2]); 
} 

Demo


旁註

:)


你可以讓你通過如下只打印拍攝的小組賽(不包括[0])預期的遵循嚴格g字面量:

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

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

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

查看String literals

+0

點 - 我一直在使用're.findall'在Python和一直期待類似的行爲。 –