is - 数据验证工具库
is 是一个全面的数据验证和类型检查工具库,提供了大量简洁易用的验证函数,涵盖常见数据类型和格式的验证需求。
安装
go get -u go-slim.dev/is快速开始
package mainimport ( "fmt" "go-slim.dev/is")func main() { // 邮箱验证 fmt.Println(is.Email("user@example.com")) // true // 手机号验证(中国大陆) fmt.Println(is.PhoneNumber("13800138000")) // true // UUID 验证 fmt.Println(is.UUID("550e8400-e29b-41d4-a716-446655440000")) // true // 范围验证 fmt.Println(is.Between(25, 18, 65)) // true // IP 地址验证 fmt.Println(is.IPv4("192.168.1.1")) // true // URL 验证 fmt.Println(is.URL("https://example.com")) // true}核心功能分类
1. 字符串格式验证
Email - 邮箱验证
func Email(str string) bool说明:验证字符串是否为有效的电子邮件地址,支持国际化邮箱,遵循 RFC 5322 标准。
示例:
is.Email("user@example.com") // trueis.Email("user+tag@domain.org") // trueis.Email("用户@example.cn") // true (支持国际化)is.Email("invalid-email") // falseis.Email("@example.com") // false (缺少用户名)PhoneNumber - 手机号验证(中国大陆)
func PhoneNumber(s string) bool说明:验证字符串是否为有效的中国大陆手机号,支持国内格式和国际格式(+86 前缀)。
示例:
is.PhoneNumber("13800138000") // trueis.PhoneNumber("+8613800138000") // trueis.PhoneNumber("12345678901") // false (无效格式)is.PhoneNumber("28001380000") // false (无效前缀)Idcard - 身份证号验证(中国大陆)
func Idcard(s string) bool说明:验证字符串是否为有效的中国身份证号。支持 15 位和 18 位格式。
示例:
is.Idcard("11010519491231002X") // true (18位带X校验位)is.Idcard("110105491231002") // true (15位格式)is.Idcard("110105194912310021") // true (18位数字校验位)is.Idcard("123456789012345") // false (无效格式)URL - URL 验证
func URL(s string) bool说明:验证字符串是否为有效的 URL。支持多种协议(http, https, ftp 等)。
示例:
is.URL("https://example.com") // trueis.URL("ftp://user:pass@host/path") // trueis.URL("http://localhost:8080") // trueis.URL("example.com") // false (缺少协议)is.URL("") // false (空字符串)2. 唯一标识符验证
UUID - 通用唯一标识符
func UUID(str string) bool // 任意版本func UUID3(str string) bool // UUID v3 (MD5哈希)func UUID4(str string) bool // UUID v4 (随机)func UUID5(str string) bool // UUID v5 (SHA-1哈希)说明:验证 UUID 格式,UUID 是 128 位的唯一标识符,通常显示为 32 个十六进制数字,以连字符分隔(8-4-4-4-12)。
示例:
// UUID v4 (最常用)is.UUID4("550e8400-e29b-41d4-a716-446655440000") // trueis.UUID4("6ba7b810-9dad-11d1-80b4-00c04fd430c8") // false (v3)// UUID v3is.UUID3("6ba7b810-9dad-11d1-80b4-00c04fd430c8") // true// UUID v5is.UUID5("6ba7b810-9dad-11d1-80b4-00c04fd430c8") // true// 任意版本is.UUID("550e8400-e29b-41d4-a716-446655440000") // trueis.UUID("not-a-uuid") // falseULID - 可排序唯一标识符
func ULID(str string) bool说明:验证是否为有效的 ULID(通用唯一字典排序标识符)。ULID 是 26 个字符的字符串,按时间排序。
示例:
is.ULID("01ARZ3NDEKTSV4RRFFQ69G5FAV") // trueis.ULID("01BX5ZZKBKACTAV9WEVGEMMVR0") // trueis.ULID("invalid-ulid") // false3. 哈希值验证
func MD4(str string) bool // MD4 哈希 (32字符)func MD5(str string) bool // MD5 哈希 (32字符)func SHA256(str string) bool // SHA-256 哈希 (64字符)func SHA384(str string) bool // SHA-384 哈希 (96字符)func SHA512(str string) bool // SHA-512 哈希 (128字符)说明:验证各种哈希摘要格式。
示例:
// MD5is.MD5("5d41402abc4b2a76b9719d911017c592") // true ("hello")is.MD5("invalid-hash") // false// SHA-256is.SHA256("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824") // true ("hello")// SHA-512is.SHA512("9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043") // true ("hello")4. 编码验证
Base64 - Base64 编码
func Base64(s string) boolfunc Base64URL(str string) bool // URL安全的Base64示例:
// 标准 Base64is.Base64("SGVsbG8gV29ybGQ=") // true ("Hello World")is.Base64("Hello World") // false (未编码)// URL 安全的 Base64is.Base64URL("SGVsbG8gV29ybGQ") // trueis.Base64URL("eyJhbGciOiJIUzI1NiIs") // true (JWT header)JWT - JSON Web Token
func JWT(str string) bool说明:验证 JWT 格式。JWT 由三部分组成,以点号分隔:header.payload.signature
示例:
is.JWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4ifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c") // trueis.JWT("invalid.jwt") // falseURLEncoded / HTMLEncoded
func URLEncoded(str string) boolfunc HTMLEncoded(str string) bool示例:
// URL 编码is.URLEncoded("Hello%20World") // trueis.URLEncoded("name%3Dvalue") // trueis.URLEncoded("Hello World") // false// HTML 实体编码is.HTMLEncoded("Hello&World") // trueis.HTMLEncoded("<div>") // trueis.HTMLEncoded("Hello & World") // false5. 字符类型验证
ASCII / Alpha / Alphanumeric
func ASCII(str string) boolfunc Alpha(str string) boolfunc Alphanumeric(str string) boolfunc AlphaUnicode(str string) boolfunc AlphanumericUnicode(str string) bool示例:
// ASCII 字符is.ASCII("Hello World") // trueis.ASCII("Héllo") // false (含非ASCII字符)// 纯字母is.Alpha("Hello") // trueis.Alpha("Hello123") // false (含数字)// 字母+数字is.Alphanumeric("Hello123") // trueis.Alphanumeric("Hello-123") // false (含连字符)// Unicode 字母is.AlphaUnicode("Héllo") // trueis.AlphaUnicode("你好") // trueis.AlphaUnicode("Привет") // true (俄语)// Unicode 字母+数字is.AlphanumericUnicode("Café123") // trueis.AlphanumericUnicode("你好123") // trueNumeric / Number / Hexadecimal
func Numeric[T any](t T) boolfunc Number[T any](t T) boolfunc Hexadecimal(str string) bool示例:
// 数值类型(包括负数、小数)is.Numeric(123) // trueis.Numeric(-45.67) // trueis.Numeric("123") // trueis.Numeric("abc") // false// 纯数字(整数)is.Number(123) // trueis.Number("123") // trueis.Number(-45) // false (负数)is.Number("12.34") // false (小数)// 十六进制is.Hexadecimal("FF00AA") // trueis.Hexadecimal("123abc") // trueis.Hexadecimal("FFGG") // false (G不是十六进制)Lowercase / Uppercase
func Lowercase(str string) boolfunc Uppercase(str string) bool示例:
// 小写is.Lowercase("hello world") // trueis.Lowercase("Hello World") // false// 大写is.Uppercase("HELLO WORLD") // trueis.Uppercase("Hello World") // false6. 颜色验证
func HEXColor(str string) boolfunc RGB(str string) boolfunc RGBA(str string) boolfunc HSL(str string) boolfunc HSLA(str string) boolfunc Color(str string) bool // 支持所有颜色格式示例:
// HEX 颜色is.HEXColor("#FF0000") // true (红色)is.HEXColor("#F00") // true (短格式)is.HEXColor("#FF000080") // true (带透明度)// RGBis.RGB("rgb(255, 0, 0)") // true (红色)is.RGB("rgb(255,255,255)") // true (白色)// RGBAis.RGBA("rgba(255, 0, 0, 0.5)") // true (半透明红色)// HSLis.HSL("hsl(0, 100%, 50%)") // true (红色)// HSLAis.HSLA("hsla(0, 100%, 50%, 0.5)") // true (半透明红色)// 通用颜色验证is.Color("#FF0000") // trueis.Color("rgb(255, 0, 0)") // trueis.Color("hsl(0, 100%, 50%)") // true7. 地理坐标验证
func Latitude[T any](t T) boolfunc Longitude[T any](t T) bool说明:
- 纬度范围:-90° 到 +90°
- 经度范围:-180° 到 +180°
示例:
// 纬度is.Latitude(45.0) // trueis.Latitude(-90.0) // true (南极)is.Latitude("90.0") // true (北极)is.Latitude(91.0) // false (超出范围)// 经度is.Longitude(120.0) // trueis.Longitude(-180.0) // trueis.Longitude("180.0") // trueis.Longitude(181.0) // false (超出范围)8. 网络验证
IP / IPv4 / IPv6
func IP(str string) boolfunc IPv4(str string) boolfunc IPv6(str string) bool示例:
// IPv4is.IPv4("192.168.1.1") // trueis.IPv4("8.8.8.8") // trueis.IPv4("127.0.0.1") // trueis.IPv4("2001:db8::1") // false (IPv6格式)// IPv6is.IPv6("2001:db8::1") // trueis.IPv6("::1") // true (localhost)is.IPv6("fe80::1") // true (link-local)is.IPv6("192.168.1.1") // false (IPv4格式)// IP (任意版本)is.IP("192.168.1.1") // trueis.IP("2001:db8::1") // trueMAC - MAC 地址
func MAC(str string) bool示例:
is.MAC("00:00:5e:00:53:01") // true (冒号分隔)is.MAC("00-00-5e-00-53-01") // true (连字符分隔)is.MAC("aa:bb:cc:dd:ee:ff") // trueis.MAC("00:00:5e:00:53") // false (字节数不足)E164 - 国际电话号码
func E164(str string) bool说明:E.164 是国际电话号码格式,格式为 +[国家代码][号码]。
示例:
is.E164("+14155552671") // true (美国)is.E164("+8613800138000") // true (中国)is.E164("14155552671") // false (缺少+)is.E164("+123") // false (太短)9. 数据格式验证
JSON - JSON 验证
func JSON[T any](t T) bool示例:
is.JSON(`{"name": "John", "age": 30}`) // trueis.JSON([]byte(`[1, 2, 3]`)) // trueis.JSON("invalid json") // falseis.JSON(123) // falseHTML - HTML 标签检测
func HTML(str string) bool示例:
is.HTML("<div>content</div>") // trueis.HTML("<p>Hello World</p>") // trueis.HTML("Hello World") // falseSemver - 语义化版本
func Semver(s string) bool说明:验证是否符合语义化版本规范 (Semantic Versioning 2.0.0),格式为 MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]。
示例:
is.Semver("1.0.0") // trueis.Semver("2.1.3-beta.2+exp.sha.5114f85") // trueis.Semver("1.0") // false (缺少PATCH)is.Semver("v1.0.0") // false (不支持v前缀)Label - 标签/变量名验证
func Label(s string) bool说明:验证是否符合变量命名规范。必须以字母 (A-F) 开头,后跟字母、数字或下划线。
示例:
is.Label("API_HOST") // trueis.Label("config_debug") // trueis.Label("1INVALID") // false (以数字开头)is.Label("api-host") // false (包含连字符)Datetime - 日期时间验证
func Datetime(str, layout string) bool说明:验证字符串是否匹配指定的时间格式。
示例:
is.Datetime("2023-12-25", "2006-01-02") // trueis.Datetime("10:30:45", "15:04:05") // trueis.Datetime("2023-12-25 10:30:45", time.RFC3339) // trueis.Datetime("invalid", "2006-01-02") // falseTimezone - 时区验证
func Timezone(str string) bool说明:验证是否为有效的 IANA 时区标识符。
示例:
is.Timezone("America/New_York") // trueis.Timezone("UTC") // trueis.Timezone("Asia/Shanghai") // trueis.Timezone("Invalid/Zone") // false10. 文件系统验证
File / Dir
func File(val any) boolfunc Dir(val any) bool示例:
// 文件检查is.File("/etc/hosts") // true (如果文件存在)is.File("./config.json") // true (如果文件存在)is.File("/tmp") // false (是目录)// 目录检查is.Dir("/tmp") // true (如果目录存在)is.Dir("./") // true (当前目录)is.Dir("/etc/hosts") // false (是文件)11. 通用验证
Empty / NotEmpty
func Empty[T any](t T) boolfunc NotEmpty[T any](t T) bool说明:检查值是否为空。空值的定义:
- 字符串、数组、切片、Map:长度为 0
- 整数、浮点数:值为 0
- 布尔值:false
- 指针、接口、通道、函数:nil
- time.Time:零值
示例:
is.Empty("") // trueis.Empty(0) // trueis.Empty(false) // trueis.Empty([]string{}) // trueis.Empty(nil) // trueis.Empty(time.Time{}) // trueis.NotEmpty("hello") // trueis.NotEmpty(42) // trueis.NotEmpty([]int{1, 2, 3}) // trueHasValue / Default
func HasValue(val any) boolfunc Default(val any) bool // HasValue 的反向说明:检查值是否不是默认静态值。
示例:
is.HasValue("hello") // trueis.HasValue(42) // trueis.HasValue(nil) // falseis.HasValue(0) // falseis.Default(0) // trueis.Default("") // trueis.Default(nil) // trueBoolean - 布尔值检查
func Boolean[T any](t T) bool说明:检查值是否可以安全转换为布尔值。
支持的值:
- 字符串:“1”, “yes”, “YES”, “on”, “ON”, “true”, “TRUE”, “0”, “no”, “NO”, “off”, “OFF”, “false”, “FALSE”
- 整数:0 或 1
- 布尔值:true 或 false
示例:
is.Boolean("true") // trueis.Boolean("yes") // trueis.Boolean(1) // trueis.Boolean(0) // trueis.Boolean(true) // trueis.Boolean("maybe") // falseis.Boolean(2) // falseOneOf - 候选值检查
func OneOf(val any, vals []any) bool说明:检查值是否在允许的候选列表中。
示例:
is.OneOf("apple", []any{"apple", "banana", "orange"}) // trueis.OneOf(5, []any{1, 2, 3, 4, 5}) // trueis.OneOf("red", []any{"green", "blue"}) // falseis.OneOf("test", []any{}) // false12. 比较验证
Compare - 通用比较
func Compare(srcVal, dstVal any, op string) bool支持的操作符:
"=":等于"!=":不等于"<":小于"<=":小于等于">":大于">=":大于等于
示例:
is.Compare(2, 3, ">") // falseis.Compare(2, 1.3, ">") // trueis.Compare("apple", "banana", "<") // true (字典序)is.Compare(true, false, ">") // trueis.Compare(time.Now(), time.Now().Add(-time.Hour), ">") // true便捷比较函数
func Equal(a, b any) boolfunc NotEqual(a, b any) boolfunc GreaterThan(a, b any) boolfunc GreaterEqualThan(a, b any) boolfunc LessThan(a, b any) boolfunc LessEqualThan(a, b any) bool示例:
is.Equal(10, 10) // trueis.NotEqual(10, 5) // trueis.GreaterThan(10, 5) // trueis.GreaterEqualThan(10, 10) // trueis.LessThan(5, 10) // trueis.LessEqualThan(10, 10) // trueBetween / NotBetween - 范围检查
func Between(val, min, max any) boolfunc NotBetween(val, min, max any) bool说明:检查值是否在(或不在)指定的闭区间内。要求 min < max,否则会 panic。
示例:
is.Between(5, 1, 10) // trueis.Between(10, 1, 10) // true (边界值)is.Between(0, 1, 10) // falseis.Between("m", "a", "z") // true (字典序)is.NotBetween(0, 1, 10) // trueis.NotBetween(11, 1, 10) // trueis.NotBetween(5, 1, 10) // false13. 长度验证
Length - 长度比较
func Length(val any, length int, op string) bool说明:验证值的长度是否满足指定条件。支持字符串、数组、切片、Map、通道。
示例:
is.Length("hello", 5, "=") // trueis.Length([]int{1, 2, 3}, 3, "=") // trueis.Length("world", 5, ">=") // trueis.Length("test", 5, "<") // trueis.Length(123, 3, "=") // false (不支持数字)LengthBetween - 长度范围
func LengthBetween(val any, min, max int) bool说明:检查值的长度是否在指定范围内(闭区间)。
示例:
is.LengthBetween("hello", 3, 8) // true (长度5)is.LengthBetween([]int{1, 2, 3}, 2, 5) // true (长度3)is.LengthBetween("world", 1, 4) // false (长度5超出)is.LengthBetween("test", 6, 10) // false (长度4不足)使用场景
1. 表单验证
type UserForm struct { Email string Phone string Age int Website string}func ValidateUserForm(form *UserForm) map[string]string { errors := make(map[string]string) // 邮箱验证 if !is.Email(form.Email) { errors["email"] = "无效的邮箱地址" } // 手机号验证 if !is.PhoneNumber(form.Phone) { errors["phone"] = "无效的手机号" } // 年龄范围验证 if !is.Between(form.Age, 18, 120) { errors["age"] = "年龄必须在18-120之间" } // 网站验证(可选) if form.Website != "" && !is.URL(form.Website) { errors["website"] = "无效的网站地址" } return errors}2. API 输入验证
type CreateProductRequest struct { Name string SKU string Price float64 Stock int Color string Description string}func ValidateProduct(req *CreateProductRequest) error { // 名称不能为空 if is.Empty(req.Name) { return fmt.Errorf("产品名称不能为空") } // 名称长度限制 if !is.LengthBetween(req.Name, 3, 100) { return fmt.Errorf("产品名称长度必须在3-100字符之间") } // SKU 格式验证(字母数字) if !is.Alphanumeric(req.SKU) { return fmt.Errorf("SKU只能包含字母和数字") } // 价格范围 if !is.GreaterThan(req.Price, 0.0) { return fmt.Errorf("价格必须大于0") } // 库存范围 if !is.Between(req.Stock, 0, 999999) { return fmt.Errorf("库存必须在0-999999之间") } // 颜色验证(可选) if req.Color != "" && !is.Color(req.Color) { return fmt.Errorf("无效的颜色值") } // 描述长度限制 if !is.Empty(req.Description) && !is.Length(req.Description, 1000, "<=") { return fmt.Errorf("描述不能超过1000字符") } return nil}3. 配置验证
type ServerConfig struct { Host string Port int SSL bool CertFile string KeyFile string}func ValidateServerConfig(cfg *ServerConfig) error { // 主机验证(IP或域名) if !is.IP(cfg.Host) && !is.Alpha(cfg.Host) { return fmt.Errorf("无效的主机地址: %s", cfg.Host) } // 端口范围 if !is.Between(cfg.Port, 1, 65535) { return fmt.Errorf("端口必须在1-65535之间") } // SSL 配置验证 if cfg.SSL { if is.Empty(cfg.CertFile) { return fmt.Errorf("启用SSL时必须提供证书文件") } if is.Empty(cfg.KeyFile) { return fmt.Errorf("启用SSL时必须提供密钥文件") } // 检查文件是否存在 if !is.File(cfg.CertFile) { return fmt.Errorf("证书文件不存在: %s", cfg.CertFile) } if !is.File(cfg.KeyFile) { return fmt.Errorf("密钥文件不存在: %s", cfg.KeyFile) } } return nil}4. 数据过滤和清理
type DataFilter struct { AllowedIPs []string AllowedEmails []string BlockedWords []string}func FilterUserInput(input map[string]any, filter *DataFilter) (map[string]any, error) { cleaned := make(map[string]any) for key, value := range input { // 处理字符串值 if strVal, ok := value.(string); ok { // HTML 注入检查 if is.HTML(strVal) { return nil, fmt.Errorf("检测到HTML标签: %s", key) } // 移除URL编码的内容 if is.URLEncoded(strVal) { // 解码处理... } cleaned[key] = strVal } // 处理IP地址 if key == "ip" { if ipStr, ok := value.(string); ok { if !is.IP(ipStr) { return nil, fmt.Errorf("无效的IP地址: %s", ipStr) } // 检查是否在允许列表 if !is.OneOf(ipStr, toAnySlice(filter.AllowedIPs)) { return nil, fmt.Errorf("IP地址不在允许列表: %s", ipStr) } cleaned[key] = ipStr } } // 处理邮箱 if key == "email" { if emailStr, ok := value.(string); ok { if !is.Email(emailStr) { return nil, fmt.Errorf("无效的邮箱地址: %s", emailStr) } cleaned[key] = strings.ToLower(emailStr) } } } return cleaned, nil}5. 数据库模型验证
type User struct { ID string Username string Email string Phone string Avatar string Bio string Website string Location struct { Lat float64 Lng float64 }}func (u *User) Validate() error { // ID 必须是 UUID if !is.UUID(u.ID) { return fmt.Errorf("无效的用户ID") } // 用户名:字母数字,3-20字符 if !is.Alphanumeric(u.Username) { return fmt.Errorf("用户名只能包含字母和数字") } if !is.LengthBetween(u.Username, 3, 20) { return fmt.Errorf("用户名长度必须在3-20字符之间") } // 邮箱验证 if !is.Email(u.Email) { return fmt.Errorf("无效的邮箱地址") } // 手机号验证(可选) if u.Phone != "" && !is.PhoneNumber(u.Phone) { return fmt.Errorf("无效的手机号") } // 头像URL验证(可选) if u.Avatar != "" && !is.URL(u.Avatar) { return fmt.Errorf("无效的头像URL") } // 个人简介长度限制 if !is.Empty(u.Bio) && !is.Length(u.Bio, 500, "<=") { return fmt.Errorf("个人简介不能超过500字符") } // 网站URL验证(可选) if u.Website != "" && !is.URL(u.Website) { return fmt.Errorf("无效的网站URL") } // 地理坐标验证 if !is.Latitude(u.Location.Lat) { return fmt.Errorf("无效的纬度值") } if !is.Longitude(u.Location.Lng) { return fmt.Errorf("无效的经度值") } return nil}6. 中间件验证
func ValidateRequestMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 验证 Content-Type contentType := c.GetHeader("Content-Type") if is.Empty(contentType) { c.AbortWithStatusJSON(400, gin.H{"error": "Content-Type is required"}) return } // 验证客户端 IP clientIP := c.ClientIP() if !is.IP(clientIP) { c.AbortWithStatusJSON(400, gin.H{"error": "Invalid client IP"}) return } // 验证 Authorization token (JWT) if token := c.GetHeader("Authorization"); token != "" { // 移除 "Bearer " 前缀 token = strings.TrimPrefix(token, "Bearer ") if !is.JWT(token) { c.AbortWithStatusJSON(401, gin.H{"error": "Invalid JWT token"}) return } } // 验证 API Key (如果存在) if apiKey := c.GetHeader("X-API-Key"); apiKey != "" { if !is.UUID(apiKey) { c.AbortWithStatusJSON(401, gin.H{"error": "Invalid API key"}) return } } c.Next() }}API 参考
字符串格式
| 函数 | 说明 |
|---|---|
Email(str string) bool | 邮箱地址 |
PhoneNumber(s string) bool | 中国手机号 |
Idcard(s string) bool | 中国身份证号 |
URL(s string) bool | URL地址 |
E164(str string) bool | E.164国际电话 |
唯一标识符
| 函数 | 说明 |
|---|---|
UUID(str string) bool | UUID (任意版本) |
UUID3/4/5(str string) bool | 特定版本UUID |
ULID(str string) bool | ULID |
哈希值
| 函数 | 说明 |
|---|---|
MD4/MD5(str string) bool | MD4/MD5哈希 |
SHA256/384/512(str string) bool | SHA系列哈希 |
编码
| 函数 | 说明 |
|---|---|
Base64(s string) bool | Base64编码 |
Base64URL(str string) bool | URL安全Base64 |
JWT(str string) bool | JSON Web Token |
URLEncoded(str string) bool | URL编码 |
HTMLEncoded(str string) bool | HTML实体编码 |
字符类型
| 函数 | 说明 |
|---|---|
ASCII(str string) bool | ASCII字符 |
Alpha(str string) bool | 纯字母 |
Alphanumeric(str string) bool | 字母+数字 |
AlphaUnicode(str string) bool | Unicode字母 |
AlphanumericUnicode(str string) bool | Unicode字母+数字 |
Numeric[T](t T) bool | 数值类型 |
Number[T](t T) bool | 纯数字 |
Hexadecimal(str string) bool | 十六进制 |
Lowercase(str string) bool | 小写字母 |
Uppercase(str string) bool | 大写字母 |
颜色
| 函数 | 说明 |
|---|---|
HEXColor(str string) bool | HEX颜色 |
RGB/RGBA(str string) bool | RGB/RGBA颜色 |
HSL/HSLA(str string) bool | HSL/HSLA颜色 |
Color(str string) bool | 任意颜色格式 |
地理和网络
| 函数 | 说明 |
|---|---|
Latitude[T](t T) bool | 纬度 |
Longitude[T](t T) bool | 经度 |
IP(str string) bool | IP地址 |
IPv4/IPv6(str string) bool | IPv4/IPv6 |
MAC(str string) bool | MAC地址 |
数据格式
| 函数 | 说明 |
|---|---|
JSON[T](t T) bool | JSON数据 |
HTML(str string) bool | HTML标签 |
Semver(s string) bool | 语义化版本 |
Label(s string) bool | 标签/变量名 |
Datetime(str, layout string) bool | 日期时间 |
Timezone(str string) bool | 时区 |
文件系统
| 函数 | 说明 |
|---|---|
File(val any) bool | 文件存在 |
Dir(val any) bool | 目录存在 |
通用验证
| 函数 | 说明 |
|---|---|
Empty[T](t T) bool | 是否为空 |
NotEmpty[T](t T) bool | 是否非空 |
HasValue(val any) bool | 是否有值 |
Default(val any) bool | 是否为默认值 |
Boolean[T](t T) bool | 布尔值检查 |
OneOf(val any, vals []any) bool | 候选值检查 |
比较
| 函数 | 说明 |
|---|---|
Compare(src, dst any, op string) bool | 通用比较 |
Equal/NotEqual(a, b any) bool | 相等/不等 |
GreaterThan/LessThan(a, b any) bool | 大于/小于 |
GreaterEqualThan/LessEqualThan(a, b any) bool | 大于等于/小于等于 |
Between(val, min, max any) bool | 范围内 |
NotBetween(val, min, max any) bool | 范围外 |
长度
| 函数 | 说明 |
|---|---|
Length(val any, length int, op string) bool | 长度比较 |
LengthBetween(val any, min, max int) bool | 长度范围 |
注意事项
1. 泛型函数
部分函数使用泛型以支持多种类型:
// 支持多种类型is.Numeric(123) // intis.Numeric(45.67) // float64is.Numeric("123") // string// 类型安全的验证is.Empty([]int{}) // 空切片is.Empty("") // 空字符串is.Empty(0) // 零值2. 正则表达式性能
大多数验证函数使用预编译的正则表达式,性能经过优化。频繁调用不会有性能问题。
3. 中国特色功能
库包含专门为中国大陆定制的验证函数:
// 手机号验证(仅中国大陆格式)is.PhoneNumber("13800138000")// 身份证号验证(中国格式)is.Idcard("11010519491231002X")4. 文件系统验证
文件和目录验证会实际检查文件系统:
// 实际检查文件是否存在is.File("/path/to/file") // 会访问文件系统// 在使用前确保路径有效if is.File(path) { // 文件存在,可以读取}5. 空值处理
理解 Empty vs HasValue vs Default 的区别:
is.Empty("") // true (长度为0)is.Empty(0) // true (零值)is.Empty(nil) // true (nil)is.HasValue("") // false (默认值)is.HasValue(0) // false (默认值)is.HasValue(42) // true (非默认值)is.Default("") // true (等于 !HasValue)is.Default(42) // false6. 比较操作的类型支持
Compare 函数支持的类型:
- 数值类型(int, float, uint 系列)
- 字符串(字典序比较)
- 布尔值(true > false)
- time.Time(时间先后)
不支持的类型会回退到 == 和 != 操作。
7. 范围验证的边界
Between 和 LengthBetween 都是闭区间(包含边界):
is.Between(1, 1, 10) // true (1 >= 1 且 1 <= 10)is.Between(10, 1, 10) // true (10 >= 1 且 10 <= 10)is.Between(0, 1, 10) // false (0 < 1)8. 错误处理
部分函数可能 panic:
// Between 要求 min < max,否则 panicis.Between(5, 10, 1) // panic: ErrBadRange在使用前确保参数有效。
最佳实践
1. 组合验证
func ValidateUsername(username string) error { if is.Empty(username) { return errors.New("用户名不能为空") } if !is.Alphanumeric(username) { return errors.New("用户名只能包含字母和数字") } if !is.LengthBetween(username, 3, 20) { return errors.New("用户名长度必须在3-20字符之间") } return nil}2. 自定义验证器
type Validator func(any) errorfunc ChainValidators(validators ...Validator) Validator { return func(val any) error { for _, v := range validators { if err := v(val); err != nil { return err } } return nil }}// 使用emailValidator := func(val any) error { if str, ok := val.(string); !ok || !is.Email(str) { return errors.New("无效的邮箱") } return nil}lengthValidator := func(val any) error { if str, ok := val.(string); !ok || !is.LengthBetween(str, 5, 100) { return errors.New("长度必须在5-100之间") } return nil}validate := ChainValidators(emailValidator, lengthValidator)3. 结构体验证
type ValidatableStruct interface { Validate() error}func ValidateStruct(v ValidatableStruct) error { return v.Validate()}// 使用type User struct { Email string Age int}func (u *User) Validate() error { if !is.Email(u.Email) { return errors.New("invalid email") } if !is.Between(u.Age, 0, 150) { return errors.New("invalid age") } return nil}4. 错误消息国际化
var validationMessages = map[string]string{ "email_invalid": "无效的邮箱地址", "phone_invalid": "无效的手机号", // ...}func ValidateWithMessage(value any, validator func(any) bool, msgKey string) error { if !validator(value) { if msg, ok := validationMessages[msgKey]; ok { return errors.New(msg) } return errors.New("验证失败") } return nil}