You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Go语言中用正则表达式将括号内数据拆分至命名分组

Go语言正则实现版本约束的命名分组提取

针对你提到的两种版本约束格式,Go语言的正则虽然不支持前后瞻,但可以通过两种方式实现需求:

方案1:单正则直接捕获(适配1-2个约束)

直接编写一个能匹配两种格式的正则,通过命名分组一次性提取所有需要的字段:

^(?P<n>\S+) \((?P<o1>[>=<~]+) (?P<v1>\S+)(?:, (?P<o2>[>=<~]+) (?P<v2>\S+))?\)$

匹配逻辑:

  • (?P<n>\S+):捕获括号外的非空白字符(即示例中的a或b)
  • (?P<o1>[>=<~]+):捕获第一个运算符
  • (?P<v1>\S+):捕获第一个版本号
  • (?:, (?P<o2>[>=<~]+) (?P<v2>\S+))?:可选的第二个约束组,仅当存在逗号分隔的第二个约束时才匹配

代码示例:

package main

import (
	"fmt"
	"regexp"
)

func main() {
	inputLines := []string{
		"a (>= 1.1)",
		"b (>= 1.1, < 2.0)",
	}
	reg := regexp.MustCompile(`^(?P<n>\S+) \((?P<o1>[>=<~]+) (?P<v1>\S+)(?:, (?P<o2>[>=<~]+) (?P<v2>\S+))?\)$`)

	for _, line := range inputLines {
		submatches := reg.FindStringSubmatch(line)
		if submatches == nil {
			fmt.Printf("无法匹配行:%s\n", line)
			continue
		}

		fmt.Printf("n -> %s\n", submatches[reg.SubexpIndex("n")])
		fmt.Printf("o1 -> %s\n", submatches[reg.SubexpIndex("o1")])
		fmt.Printf("v1 -> %s\n", submatches[reg.SubexpIndex("v1")])
		
		o2Idx := reg.SubexpIndex("o2")
		if o2Idx != -1 && submatches[o2Idx] != "" {
			fmt.Printf("o2 -> %s\n", submatches[o2Idx])
			fmt.Printf("v2 -> %s\n", submatches[reg.SubexpIndex("v2")])
		}
		fmt.Println("---")
	}
}

方案2:两步处理(支持任意数量约束)

如果需要支持3个及以上的版本约束,建议先捕获名称和整体约束内容,再拆分单个约束:

  1. 第一步正则捕获名称和括号内的所有约束:
^(?P<n>\S+) \((?P<constraints>(?:[>=<~]+ \S+(?:, )?)+)\)$
  1. 第二步用简单正则([>=<~]+) (\S+)循环匹配constraints内容,提取每一组运算符和版本号。

代码示例:

package main

import (
	"fmt"
	"regexp"
)

func main() {
	inputLines := []string{
		"a (>= 1.1)",
		"b (>= 1.1, < 2.0)",
		"c (> 0.5, <= 1.0, != 0.8)",
	}
	regMain := regexp.MustCompile(`^(?P<n>\S+) \((?P<constraints>(?:[>=<~]+ \S+(?:, )?)+)\)$`)
	regConstraint := regexp.MustCompile(`([>=<~]+) (\S+)`)

	for _, line := range inputLines {
		mainMatch := regMain.FindStringSubmatch(line)
		if mainMatch == nil {
			fmt.Printf("无法匹配行:%s\n", line)
			continue
		}

		name := mainMatch[regMain.SubexpIndex("n")]
		constraints := mainMatch[regMain.SubexpIndex("constraints")]
		
		fmt.Printf("n -> %s\n", name)
		matches := regConstraint.FindAllStringSubmatch(constraints, -1)
		for i, match := range matches {
			fmt.Printf("o%d -> %s\n", i+1, match[1])
			fmt.Printf("v%d -> %s\n", i+1, match[2])
		}
		fmt.Println("---")
	}
}

内容的提问来源于stack exchange,提问作者Tomer S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 23:35:21