为了账号安全,请及时绑定邮箱和手机立即绑定

解析文本文件以匹配字符串并提取值(在 Golang 中)

解析文本文件以匹配字符串并提取值(在 Golang 中)

Go
交互式爱情 2021-11-29 19:12:26
我正在摸索一个似乎可能很常见的需求,但我无法在网络上找到任何示例。我有一个这样的文件:  answer VNET_1_DHCP yes  answer VNET_1_DHCP_CFG_HASH 4CF2C196E368CE83B9D1895C5E05301CDFDEBCA0    answer VNET_1_HOSTONLY_NETMASK 255.255.255.0  answer VNET_1_HOSTONLY_SUBNET 192.168.224.0  answer VNET_1_VIRTUAL_ADAPTER yes  answer VNET_8_DHCP yes  answer VNET_8_DHCP_CFG_HASH D326C0BC7FF6C38C57AF341F9075E576C175B250  answer VNET_8_HOSTONLY_NETMASK 255.255.255.0  answer VNET_8_HOSTONLY_SUBNET 172.16.102.0  answer VNET_8_NAT yes  answer VNET_8_VIRTUAL_ADAPTER yes我需要提取特定子网 (192.168.224.0) 的 VNET 编号。VNET 数量可能会有所不同(理论上,子网甚至可能不存在)。所以我需要匹配子网是否存在,如果存在则提取网络号(1在本例中)。我发现在 BASH 中实现它非常容易: if grep -q 192.168.224.0 ./networking; then      echo "The ${VMNET_SUBNET} network already exists"      NETWORK_NUMBER=$(grep ${VMNET_SUBNET} ./networking | cut -d'_' -f 2)      echo NETWORK_NUMBER   else <do something to create it.....> 我试图找到使用 Go 实现这一点的最简单方法。
查看完整描述

3 回答

?
jeck猫

TA贡献1909条经验 获得超7个赞

您可以使用正则表达式:


re := regexp.MustCompile(`.*VNET_(\d+)_.*192.168.224.0`)

matches := re.FindStringSubmatch(text)

fmt.Println(matches[1])

游乐场:http : //play.golang.org/p/NQlA2BObtU。


查看完整回答
反对 回复 2021-11-29
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

这是一种基于@ainar-g 的答案解析这些数据的可靠方法:


http://play.golang.org/p/6-PELcLvVz


此处的目标是使用以下类型将每个 VNET 的属性存储在映射中:


type vnet map[int]map[string]string

这段代码:


var re = regexp.MustCompile(`.*VNET_(\d+)_([^\s]+) (.*)`)

func ReadVnet(r io.Reader) vnet {

    s := bufio.NewScanner(r)

    v := make(vnet)


    for s.Scan() {

        matches := re.FindStringSubmatch(s.Text())

        id, err := strconv.Atoi(matches[1])

        if err != nil {

            continue

        }


        if _, ok := v[id]; !ok {

            v[id] = make(map[string]string)

        }

        v[id][matches[2]] = matches[3]

    }


    return v

}

创建有问题的地图:


map[1:map[DHCP:yes DHCP_CFG_HASH:4CF2C196E368CE83B9D1895C5E05301CDFDEBCA0 HOSTONLY_NETMASK:255.255.255.0 HOSTONLY_SUBNET:192.168.224.0 VIRTUAL_ADAPTER:yes] 8:map[DHCP:yes DHCP_CFG_HASH:D326C0BC7FF6C38C57AF341F9075E576C175B250 HOSTONLY_NETMASK:255.255.255.0 HOSTONLY_SUBNET:172.16.102.0 NAT:yes VIRTUAL_ADAPTER:yes]]

现在您可以在地图上迭代以找到感兴趣的项目:


func main() {

    v := ReadVnet(bytes.NewBufferString(text))


    for id, properties := range v {

        if ip, ok := properties["HOSTONLY_SUBNET"]; ok && ip == "192.168.224.0" {

            fmt.Println(id)

            return

        }

    }

}


查看完整回答
反对 回复 2021-11-29
?
四季花海

TA贡献1811条经验 获得超5个赞

这是一个没有正则表达式的版本:


  idxEnd := strings.Index(txt, "192.168.224.0")

  idxVNET := strings.LastIndex(txt[:idxEnd], "VNET_")

  beginNumber := idxVNET + 5

  length := strings.Index(txt[beginNumber:idxEnd], "_")

  number, _ := strconv.Atoi(txt[beginNumber : beginNumber+length])

  fmt.Printf("number: %T %v\n", number, number)

你会尝试在一个非常(非常)大的字符串上这样做,它应该更快。


查看完整回答
反对 回复 2021-11-29
  • 3 回答
  • 0 关注
  • 282 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信