go 标准库的 `regexp` 包不支持环视(lookaround)语法(如 `(?
Go 的 regexp 包基于 RE2 引擎,明确不支持所有类型的环视断言(包括正向/负向先行断言 (?=...)/(?!...) 和正向/负向后行断言 (?
panic: regexp: Compile(`'(.*?)(?✅ 推荐解决方案:用交替(alternation)规避转义问题
核心思路是:将“以非反斜杠结尾的单引号”这一逻辑,转化为两种明确可匹配的情形:
对应正则为:
re := regexp.MustCompile(`'(.*?[^\\]|)'`)
? 解析该模式:
⚠️ 注意:此写法依赖 .*?[^\\] 的“非贪婪+否定字符类”组合来隐式排除 \ 结尾,但存在边界风险:若字符串以 \ 结尾(如 'abc\'),该模式仍可能错误匹配(因 .*? 可能吞掉 \ 前的字符使 [^\\] 匹配成功)。更健壮的做法是预处理——先移除所有已转义的单引号(\' → " 或其他临时标记),再用简单正则提取,最后还原。
package main
import (
"fmt"
"regexp"
"strings"
)
// safeExtractEnumValues 从类似 ENUM('v1','v2','v\'3') 的字符串中提取未转义的值
func safeExtractEnumValues(enumDef string) []string {
// Step 1: 将 \' 替换为占位符(如 \x00),避免干扰匹配
processed := strings.ReplaceAll(enumDef, `\'`, "\x00")
// Step 2: 匹配 '...'; 允许空字符串,且不关心内部是否含 \x00
re := regexp.MustCompile(`'([^']*)'`)
matches := re.FindAllStringSubmatch([]byte(processed), -1)
// Step 3: 还原 \x00 → '
var result []string
for _, m := range matches {
s := strings.Trim(string(m), "'")
s = strings.ReplaceAll(s, "\x00", "'")
result = append(result, s)
}
return result
}
func main() {
raw := `ENUM('value1','value2','value\'s3','')`
values := safeExtractEnumValues(raw)
fmt.Println(values) // 输出: [value1 value2 value's3 ]
}
综上,放弃环视幻想,拥抱分步预处理——这是 Go 生态中处理此类字符串提取问题最务实、最可靠的技术路径。