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

Go语言validator密码验证问题:正则报错且oneof无法添加特殊字符

解决go-playground/validator/v10密码验证问题

问题分析

  1. oneof标签误用:oneof是用来匹配枚举固定值的(比如oneof=admin user guest),完全不适合用来检查密码是否包含不同类型的字符,所以你第一个验证规则根本不生效。
  2. 正则表达式错误:你写的正则^(?=.*[a-zA-Z0-9!@#$%^&.?/]).$有两处关键问题:
    • 末尾的.仅匹配单个字符,应该改为.*才能匹配任意长度的密码;
    • 正则没有分别校验大写、小写、数字、特殊字符四个条件,只是检查包含其中一类,不符合需求;
    • 正则语法错误导致validator解析失败,抛出"undefined"错误。

正确解决方案

方案一:自定义验证函数(推荐,可读性更高)

自定义一个验证函数,明确检查四个要求:

package main

import (
	"fmt"
	"unicode"

	"github.com/go-playground/validator/v10"
)

// 自定义密码验证逻辑
func validatePassword(fl validator.FieldLevel) bool {
	password := fl.Field().String()
	var (
		hasUpper   bool
		hasLower   bool
		hasNumber  bool
		hasSpecial bool
	)
	// 定义允许的特殊字符集合
	specialChars := map[rune]bool{
		'@': true, '#': true, '$': true, '%': true,
		'^': true, '&': true, '.': true, '?': true,
	}

	for _, char := range password {
		switch {
		case unicode.IsUpper(char):
			hasUpper = true
		case unicode.IsLower(char):
			hasLower = true
		case unicode.IsNumber(char):
			hasNumber = true
		case specialChars[char]:
			hasSpecial = true
		}
	}
	// 必须同时满足四个条件
	return hasUpper && hasLower && hasNumber && hasSpecial
}

type UserReg struct {
	Username        string `validate:"required,min=4,max=15"`
	Email           string `validate:"required,email"`
	Password        string `validate:"required,min=8,max=20,eqfield=ConfirmPassword,password"`
	ConfirmPassword string `validate:"required,min=8,max=20"`
}

func main() {
	validate := validator.New()
	// 注册自定义验证器
	if err := validate.RegisterValidation("password", validatePassword); err != nil {
		fmt.Println("注册验证器失败:", err)
		return
	}

	ut := UserReg{
		Username:        "Joe23",
		Email:           "Joe@joe.com",
		Password:        "Pa$$w0rd",
		ConfirmPassword: "Pa$$w0rd",
	}

	err := validate.Struct(ut)
	fmt.Println(err) // 验证通过时输出 <nil>
}

方案二:修正正则表达式

使用正确的正向预查正则,注意用反引号包裹结构体标签避免转义问题:

type UserReg2 struct {
	Username        string `validate:"required,min=4,max=15"`
	Email           string `validate:"required,email"`
	Password        string `validate:"required,min=8,max=20,eqfield=ConfirmPassword,regexp=^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[@#$%^&.?]).+$"`
	ConfirmPassword string `validate:"required,min=8,max=20,regexp=^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[@#$%^&.?]).+$"`
}

正则规则说明:

  • (?=.*[A-Z]):确保包含至少一个大写字母
  • (?=.*[a-z]):确保包含至少一个小写字母
  • (?=.*[0-9]):确保包含至少一个数字
  • (?=.*[@#$%^&.?]):确保包含至少一个指定的特殊字符
  • .+$:匹配任意长度的有效字符(配合min/max标签控制密码长度)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:50:21