4

我有以下文本文件,我想解析出来以获取各个字段:

host_group_web = ( )
host_group_lbnorth = ( lba050 lbhou002 lblon003 )

我要提取的字段以粗体显示

  • host_group_web = ( )
  • host_group_lbnorth = ( lba505 lbhou002 lblon003 )

host_group_web 在( )之间没有任何项目,因此该部分将被忽略

我将第一个组命名为nodegroup并将 () 之间的项目命名为节点

我正在逐行读取文件,并存储结果以供进一步处理。

在 Golang 中,这是我正在使用的正则表达式的片段:

hostGroupLine := "host_group_lbnorth = ( lba050 lbhou002 lblon003 )"
hostGroupExp := regexp.MustCompile(`host_group_(?P<nodegroup>[[:alnum:]]+)\s*=\s*\(\s*(?P<nodes>[[:alnum:]]+\s*)`)
hostGroupMatch := hostGroupExp.FindStringSubmatch(hostGroupLine)

for i, name := range hostGroupExp.SubexpNames() {
  if i != 0 {
    fmt.Println("GroupName:", name, "GroupMatch:", hostGroupMatch[i])
  }
}

我得到以下输出,其中缺少名为 group的节点的其余匹配项。

GroupName: nodegroup GroupMatch: lbnorth
GroupName: nodes GroupMatch: lba050

Golang Playground 中的片段

我的问题是,如何在 Golang 中获得一个匹配节点组和所有可能在行中的节点的正则表达式,例如 lba050 lbhou002 lblon003。节点的数量会有所不同,从 0 到尽可能多。

4

1 回答 1

5

如果要捕获组名称和所有可能的节点名称,则应使用不同的正则表达式模式。这个应该一口气捕获所有这些。无需使用命名捕获组,但如果您愿意,可以。

hostGroupExp := regexp.MustCompile(`host_group_([[:alnum:]]+)|([[:alnum:]]+) `)

hostGroupLine := "host_group_lbnorth = ( lba050 lbhou002 lblon003 )"
hostGroupMatch := hostGroupExp.FindAllStringSubmatch(hostGroupLine, -1)

fmt.Printf("GroupName: %s\n", hostGroupMatch[0][1])
for i := 1; i < len(hostGroupMatch); i++ {
    fmt.Printf("  Node: %s\n", hostGroupMatch[i][2])
}

操场上看它

选择:

您还可以像awk那样进行解析:使用正则表达式将行拆分为标记并打印您需要的标记。当然,线路布局应该与您的示例中给出的相同。

package main

import (
    "fmt"
    "regexp"
)

func printGroupName(tokens []string) {
    fmt.Printf("GroupName: %s\n", tokens[2])
    for i := 5; i < len(tokens)-1; i++ {
        fmt.Printf("  Node: %s\n", tokens[i])
    }
}

func main() {

    // regexp line splitter (either _ or space)
    r := regexp.MustCompile(`_| `)

    // lines to parse
    hostGroupLines := []string{
        "host_group_lbnorth = ( lba050 lbhou002 lblon003 )",
        "host_group_web = ( web44 web125 )",
        "host_group_web = ( web44 )",
        "host_group_lbnorth = ( )",
    }

    // split lines on regexp splitter and print result
    for _, line := range hostGroupLines {
        hostGroupMatch := r.Split(line, -1)
        printGroupName(hostGroupMatch)
    }

}

操场上看它

于 2016-11-05T19:18:57.733 回答