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

如何检测字符串含连续重复字符?Go正则表达式报错求助

解决方案:Go中密码连续重复字符校验问题

问题根源

Go标准库的regexp包基于RE2正则语法,不支持Perl风格的前瞻/后顾断言(比如(?!...)这类语法),这就是你遇到invalid or unsupported Perl syntax: '(?!'报错的核心原因。regexp.MustCompile只是预编译正则表达式的工具,无法解决语法兼容性问题。

两种可行解决方案

方案1:使用RE2兼容的正则表达式

根据需求调整正则语法,RE2支持反向引用\1,可以直接匹配连续重复的字符:

  • 如果需求是检测密码是否包含至少2个连续相同字符:
    正则写成(.)\1,直接匹配任意一组连续重复的两个字符。

    代码示例:

    package main
    
    import (
        "errors"
        "fmt"
        "regexp"
    )
    
    // 预编译正则,避免重复编译开销
    var twoConsecutiveRegex = regexp.MustCompile(`(.)\1`)
    
    func validatePassword(password string) error {
        // 检测是否存在两个连续相同字符
        if twoConsecutiveRegex.MatchString(password) {
            return errors.New("密码不能包含连续重复的字符")
        }
    
        // 其他密码校验逻辑(比如长度、包含大小写等)
        if len(password) < 8 {
            return errors.New("密码长度不能少于8位")
        }
    
        return nil
    }
    
    func main() {
        testPasswords := []string{"abc123", "aab123", "abcdd123"}
        for _, pwd := range testPasswords {
            err := validatePassword(pwd)
            if err != nil {
                fmt.Printf("密码%s校验失败:%v\n", pwd, err)
            } else {
                fmt.Printf("密码%s校验通过\n", pwd)
            }
        }
    }
    
  • 如果原需求是禁止密码出现3个连续相同字符:
    正则写成(.)\1\1,匹配任意一组连续三个相同字符,然后取反判断即可。

方案2:纯Go代码检测(更高效)

对于简单的连续字符检测,纯代码实现比正则更高效,也避免了语法兼容性问题:

package main

import (
	"errors"
	"fmt"
)

// 检测字符串是否包含n个连续相同字符
func hasConsecutiveSameChars(s string, n int) bool {
	if len(s) < n {
		return false
	}
	for i := 0; i <= len(s)-n; i++ {
		isSame := true
		for j := 1; j < n; j++ {
			if s[i] != s[i+j] {
				isSame = false
				break
			}
		}
		if isSame {
			return true
		}
	}
	return false
}

func validatePassword(password string) error {
	// 检测是否有2个连续相同字符
	if hasConsecutiveSameChars(password, 2) {
		return errors.New("密码不能包含连续重复的字符")
	}

	// 其他校验逻辑
	if len(password) < 8 {
		return errors.New("密码长度不能少于8位")
	}

	return nil
}

func main() {
	testPasswords := []string{"abc123", "aab123", "abcdd123"}
	for _, pwd := range testPasswords {
		err := validatePassword(pwd)
		if err != nil {
			fmt.Printf("密码%s校验失败:%v\n", pwd, err)
		} else {
			fmt.Printf("密码%s校验通过\n", pwd)
		}
	}
}

总结

  • 避免在Go的regexp中使用Perl风格的前瞻/后顾断言,改用RE2支持的语法;
  • 简单的字符检测场景,纯代码实现更直观高效;
  • regexp.MustCompile的作用是预编译正则,减少重复编译的性能开销,但无法解决语法不兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:20:21