如何检测字符串含连续重复字符?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
相关产品推荐
相关产品推荐

