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

Golang下匹配无嵌套括号外&&的无负向预查正则方案

需求说明

给定表达式:

{field1} == value1 && {field2} == value2  && ({field3} == value3 && {field4} == value4) && {field5} == value5

需要匹配所有括号外的&&(忽略括号内value3与field4之间的&&),最终按这些括号外的&&分割,得到两个结果:

  1. 匹配到的&&列表:[&&, &&, &&]
  2. 分割后的表达式片段列表:[{field1} == value1, {field2} == value2, ({field3} == value3 && {field4} == value4), {field5} == value5]

原正则(\&\&)(?![^\(]*\))可实现需求,但Golang不支持负向预查,以下是无负向预查的实现方案:


方案一:手动遍历字符串(推荐)

通过遍历字符串跟踪括号嵌套深度,当深度为0时遇到的&&即为目标匹配项,同时记录分割点。该方案逻辑清晰,支持多层嵌套括号,不受正则特性限制。

示例代码:

package main

import (
	"fmt"
	"strings"
)

func splitOutsideParens(s string) ([]string, []string) {
	var ands []string
	var parts []string
	var current strings.Builder
	depth := 0

	for i := 0; i < len(s); i++ {
		switch s[i] {
		case '(':
			depth++
			current.WriteByte(s[i])
		case ')':
			depth--
			current.WriteByte(s[i])
		case '&':
			// 检查是否为&&且当前处于括号外(深度为0)
			if i+1 < len(s) && s[i+1] == '&' && depth == 0 {
				parts = append(parts, strings.TrimSpace(current.String()))
				current.Reset()
				ands = append(ands, "&&")
				i++ // 跳过下一个&
			} else {
				current.WriteByte(s[i])
			}
		default:
			current.WriteByte(s[i])
		}
	}
	// 添加最后一段内容
	if current.Len() > 0 {
		parts = append(parts, strings.TrimSpace(current.String()))
	}

	return ands, parts
}

func main() {
	input := "{field1} == value1 && {field2} == value2  && ({field3} == value3 && {field4} == value4) && {field5} == value5"
	ands, parts := splitOutsideParens(input)
	fmt.Printf("[%s]\n", strings.Join(ands, ", "))
	fmt.Printf("[%s]\n", strings.Join(parts, ", "))
}

运行结果:

[&&, &&, &&]
[{field1} == value1, {field2} == value2, ({field3} == value3 && {field4} == value4), {field5} == value5]

方案二:Golang正则模拟(仅适用于单层括号场景)

利用正则捕获组区分括号内内容与括号外的&&,但该方案仅支持单层括号,多层嵌套时会失效。

示例代码:

package main

import (
	"fmt"
	"regexp"
	"strings"
)

func main() {
	input := "{field1} == value1 && {field2} == value2  && ({field3} == value3 && {field4} == value4) && {field5} == value5"
	re := regexp.MustCompile(`(\([^()]*\))|(&&)`)

	var ands []string
	var parts []string
	var temp strings.Builder
	matches := re.FindAllStringSubmatchIndex(input, -1)

	prev := 0
	for _, match := range matches {
		// 写入当前匹配前的内容
		temp.WriteString(input[prev:match[0]])
		prev = match[1]

		if match[2] != -1 {
			// 匹配到括号内容,直接写入
			temp.WriteString(input[match[2]:match[3]])
		} else if match[4] != -1 {
			// 匹配到括号外的&&,记录片段和&&
			parts = append(parts, strings.TrimSpace(temp.String()))
			temp.Reset()
			ands = append(ands, "&&")
		}
	}
	// 添加最后一段内容
	if prev < len(input) {
		temp.WriteString(input[prev:])
		parts = append(parts, strings.TrimSpace(temp.String()))
	}

	fmt.Printf("[%s]\n", strings.Join(ands, ", "))
	fmt.Printf("[%s]\n", strings.Join(parts, ", "))
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:43:20