2017-09-05 226 views
0

我在查找返回map[string]interface{}的函數,其中interface{}可以是切片,map[string]interface{}或值。在golang正則表達式中獲取子組的名單

我的用例是解析像下面這樣的WKT幾何體並檢索點值;例如,對於一個圓環多邊形:

POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0),(3 3, 3 7, 7 7, 7 3, 3 3))

正則表達式(匹配只對可讀性目的整數餘自願集\ d):

(POLYGON \(
    (?P<polygons>\(
     (?P<points>(?P<point>(\d \d),){3,}) 
     (?P<last_point>\d \d)\),)* 
    (?P<last_polygon>\(
     (?P<points>(?P<point>(\d \d),){3,}) 
     (?P<last_point>\d \d)\))\) 
) 

我有一個函數(從SO複製),該檢索一些信息,但它不是一個嵌套組,良好的和團體的名單:

func getRegexMatchParams(reg *regexp.Regexp, url string) (paramsMap map[string]string) { 
    match := reg.FindStringSubmatch(url) 
    paramsMap = make(map[string]string) 
    for i, name := range reg.SubexpNames() { 
     if i > 0 && i <= len(match) { 
      paramsMap[name] = match[i] 
     } 
    } 
    return match 
} 

看來這組point只獲得1分。 example on playground

[編輯]我要的結果是這樣的:

map[string]interface{}{ 
    "polygons": map[string]interface{} { 
     "points": []interface{}{ 
      {map[string]string{"point": "0 0"}},  
      {map[string]string{"point": "0 10"}},   
      {map[string]string{"point": "10 10"}},   
      {map[string]string{"point": "10 0"}}, 
     }, 
     "last_point": "0 0", 
    }, 
    "last_polygon": map[string]interface{} { 
     "points": []interface{}{ 
      {map[string]string{"point": "3 3"}},  
      {map[string]string{"point": "3 7"}},   
      {map[string]string{"point": "7 7"}},   
      {map[string]string{"point": "7 3"}}, 
     }, 
     "last_point": "3 3", 
    } 
} 

所以我還可以用它爲不同的目的,如查詢數據庫和驗證last_point =點,每個多邊形[0]。

回答

2

嘗試添加一些空格到正則表達式。

還要注意的是這臺發動機將不保留是一個量化的外部分組內
(a|b|c)+所有捕獲組值,其中該組將只包含最後a或b或c發現。

而且,你的正則表達式可以減少到這

(POLYGON\s*\((?P<polygons>\(\s*(?P<points>(?P<point>\s*(\d+\s+\d+)\s*,){3,})\s*(?P<last_point>\d+\s+\d+)\s*\)(?:\s*,\s*|\s*\)))+)

https://play.golang.org/p/rLaaEa_7GX


原:

(POLYGON\s*\((?P<polygons>\(\s*(?P<points>(?P<point>\s*(\d+\s+\d+)\s*,){3,})\s*(?P<last_point>\d+\s+\d+)\s*\),)*(?P<last_polygon>\(\s*(?P<points>(?P<point>\s*(\d+\s+\d+)\s*,){3,})\s*(?P<last_point>\d+\s+\d+)\s*\))\s*\))

https://play.golang.org/p/rZgJYPDMzl

請參閱下文了解這些組包含的內容。

(       # (1 start) 
     POLYGON \s* \(
     (?P<polygons>     # (2 start) 
      \(\s* 
      (?P<points>     # (3 start) 
       (?P<point>     # (4 start) 
        \s* 
        (\d+ \s+ \d+)    # (5) 
        \s* 
        , 
       ){3,}       # (4 end) 
      )        # (3 end) 
      \s*    
      (?P<last_point> \d+ \s+ \d+) # (6) 
      \s* \), 
    )*       # (2 end) 
     (?P<last_polygon>    # (7 start) 
      \(\s* 
      (?P<points>     # (8 start) 
       (?P<point>     # (9 start) 
        \s* 
        (\d+ \s+ \d+)    # (10) 
        \s* 
        , 
       ){3,}       # (9 end) 
      )        # (8 end) 
      \s* 
      (?P<last_point> \d+ \s+ \d+) # (11) 
      \s* \) 
    )        # (7 end) 
     \s* \) 
)        # (1 end) 

輸入

POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0),(3 3, 3 7, 7 7, 7 3, 3 3)) 

輸出

** Grp 0    - (pos 0 , len 65) 
POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0),(3 3, 3 7, 7 7, 7 3, 3 3)) 
** Grp 1    - (pos 0 , len 65) 
POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0),(3 3, 3 7, 7 7, 7 3, 3 3)) 
** Grp 2 [polygons]  - (pos 9 , len 30) 
(0 0, 0 10, 10 10, 10 0, 0 0), 
** Grp 3 [points]  - (pos 10 , len 23) 
0 0, 0 10, 10 10, 10 0, 
** Grp 4 [point]  - (pos 27 , len 6) 
10 0, 
** Grp 5    - (pos 28 , len 4) 
10 0 
** Grp 6 [last_point] - (pos 34 , len 3) 
0 0 
** Grp 7 [last_polygon] - (pos 39 , len 25) 
(3 3, 3 7, 7 7, 7 3, 3 3) 
** Grp 8 [points]  - (pos 40 , len 19) 
3 3, 3 7, 7 7, 7 3, 
** Grp 9 [point]  - (pos 54 , len 5) 
7 3, 
** Grp 10    - (pos 55 , len 3) 
7 3 
** Grp 11 [last_point] - (pos 60 , len 3) 
3 3 

可能的解決方案

這不是不可能的。它只需要一些額外的步驟。
(順便說一下,是不是有一個WKT庫可以解析這個給你嗎?)

現在,我不知道你的語言能力,所以這只是一個普遍的方法。

1.驗證您要解析的表單。
這將驗證並返回所有多邊形集合作爲All_Polygons組中的單個字符串。

目標POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0),(3 3, 3 7, 7 7, 7 3, 3 3))

POLYGON\s*\((?P<All_Polygons>(?:\(\s*\d+\s+\d+(?:\s*,\s*\d+\s+\d+){2,}\s*\))(?:\s*,\(\s*\d+\s+\d+(?:\s*,\s*\d+\s+\d+){2,}\s*\))*)\s*\)

** Grp 1 [All_Polygons] - (pos 9 , len 55) 
(0 0, 0 10, 10 10, 10 0, 0 0),(3 3, 3 7, 7 7, 7 3, 3 3) 

2.如果1是成功的,設置使用All_Polygons串的輸出的循環的匹配。

目標(0 0, 0 10, 10 10, 10 0, 0 0),(3 3, 3 7, 7 7, 7 3, 3 3)

(?:\(\s*(?P<Single_Poly_All_Pts>\d+\s+\d+(?:\s*,\s*\d+\s+\d+){2,})\s*\))

這一步是等同的找到所有類型的比賽。它應該匹配在Single_Poly_All_Pts組字符串中返回的單個多邊形的所有點的連續值。

這將會給你這2場單獨的比賽,這可以被放入一個臨時陣列,具有2名值的字符串:

** Grp 1 [Single_Poly_All_Pts] - (pos 1 , len 27) 
0 0, 0 10, 10 10, 10 0, 0 0 

** Grp 1 [Single_Poly_All_Pts] - (pos 31 , len 23) 
3 3, 3 7, 7 7, 7 3, 3 3 

3.如果2是成功的,設置使用臨時數組循環比賽輸出步驟2.
這會給你個別點的每個多邊形。

(?P<Single_Point>\d+\s+\d+)

再次,這是一個循環的匹配(或找到所有類型匹配的)。對於每個陣列元素
(多邊形),這將產生各個點。

目標[件1] 0 0, 0 10, 10 10, 10 0, 0 0

** Grp 1 [Single_Point] - (pos 0 , len 3) 
0 0 
** Grp 1 [Single_Point] - (pos 5 , len 4) 
0 10 
** Grp 1 [Single_Point] - (pos 11 , len 5) 
10 10 
** Grp 1 [Single_Point] - (pos 18 , len 4) 
10 0 
** Grp 1 [Single_Point] - (pos 24 , len 3) 
0 0 

而且,

目標[件2] 3 3, 3 7, 7 7, 7 3, 3 3

** Grp 1 [Single_Point] - (pos 0 , len 3) 
3 3 
** Grp 1 [Single_Point] - (pos 5 , len 3) 
3 7 
** Grp 1 [Single_Point] - (pos 10 , len 3) 
7 7 
** Grp 1 [Single_Point] - (pos 15 , len 3) 
7 3 
** Grp 1 [Single_Point] - (pos 20 , len 3) 
3 3 
+0

謝謝您的簡化,但是這不是我問。我編輯了我的問題,以更具體地說明預期的結果 – GwydionFR

+0

@GwydionFR - 它可能不是您想要聽到的答案,但它告訴了您爲什麼您從未在「point」中獲得超過1個值。這個'(?d (\ d \ d),){3,}'是一個量化的捕獲組。這個組只包含它找到的最後一個'\ d \ d'。此外,您也有重複的捕獲組名稱。 – sln

+0

那麼這意味着不可能得到我想要的結果?如果這是一種語言限制,那麼我很好,我可以關閉這個主題 – GwydionFR