is - 数据验证工具库
is 是一个全面的数据验证和类型检查工具库,提供了大量简洁易用的验证函数,涵盖常见数据类型和格式的验证需求。
安装
go get -u go-slim.dev/is
快速开始
package main
import (
"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") // true
is.Email("user+tag@domain.org") // true
is.Email("用户@example.cn") // true (支持国际化)
is.Email("invalid-email") // false
is.Email("@example.com") // false (缺少用户名)
PhoneNumber - 手机号验证(中国大陆)
func PhoneNumber(s string) bool
说明:验证字符串是否为有效的中国大陆手机号,支持国内格式和国际格式(+86 前缀)。
示例:
is.PhoneNumber("13800138000") // true
is.PhoneNumber("+8613800138000") // true
is.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") // true
is.URL("ftp://user:pass@host/path") // true
is.URL("http://localhost:8080") // true
is.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") // true
is.UUID4("6ba7b810-9dad-11d1-80b4-00c04fd430c8") // false (v3)
// UUID v3
is.UUID3("6ba7b810-9dad-11d1-80b4-00c04fd430c8") // true
// UUID v5
is.UUID5("6ba7b810-9dad-11d1-80b4-00c04fd430c8") // true
// 任意版本
is.UUID("550e8400-e29b-41d4-a716-446655440000") // true
is.UUID("not-a-uuid") // false
ULID - 可排序唯一标识符
func ULID(str string) bool
说明:验证是否为有效的 ULID(通用唯一字典排序标识符)。ULID 是 26 个字符的字符串,按时间排序。
示例:
is.ULID("01ARZ3NDEKTSV4RRFFQ69G5FAV") // true
is.ULID("01BX5ZZKBKACTAV9WEVGEMMVR0") // true
is.ULID("invalid-ulid") // false
3. 哈希值验证
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字符)
说明:验证各种哈希摘要格式。
示例:
// MD5
is.MD5("5d41402abc4b2a76b9719d911017c592") // true ("hello")
is.MD5("invalid-hash") // false
// SHA-256
is.SHA256("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824") // true ("hello")
// SHA-512
is.SHA512("9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043") // true ("hello")
4. 编码验证
Base64 - Base64 编码
func Base64(s string) bool
func Base64URL(str string) bool // URL安全的Base64
示例:
// 标准 Base64
is.Base64("SGVsbG8gV29ybGQ=") // true ("Hello World")
is.Base64("Hello World") // false (未编码)
// URL 安全的 Base64
is.Base64URL("SGVsbG8gV29ybGQ") // true
is.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") // true
is.JWT("invalid.jwt") // false
URLEncoded / HTMLEncoded
func URLEncoded(str string) bool
func HTMLEncoded(str string) bool
示例:
// URL 编码
is.URLEncoded("Hello%20World") // true
is.URLEncoded("name%3Dvalue") // true
is.URLEncoded("Hello World") // false
// HTML 实体编码
is.HTMLEncoded("Hello&World") // true
is.HTMLEncoded("<div>") // true
is.HTMLEncoded("Hello & World") // false
5. 字符类型验证
ASCII / Alpha / Alphanumeric
func ASCII(str string) bool
func Alpha(str string) bool
func Alphanumeric(str string) bool
func AlphaUnicode(str string) bool
func AlphanumericUnicode(str string) bool
示例:
// ASCII 字符
is.ASCII("Hello World") // true
is.ASCII("Héllo") // false (含非ASCII字符)
// 纯字母
is.Alpha("Hello") // true
is.Alpha("Hello123") // false (含数字)
// 字母+数字
is.Alphanumeric("Hello123") // true
is.Alphanumeric("Hello-123") // false (含连字符)
// Unicode 字母
is.AlphaUnicode("Héllo") // true
is.AlphaUnicode("你好") // true
is.AlphaUnicode("Привет") // true (俄语)
// Unicode 字母+数字
is.AlphanumericUnicode("Café123") // true
is.AlphanumericUnicode("你好123") // true
Numeric / Number / Hexadecimal
func Numeric[T any](t T) bool
func Number[T any](t T) bool
func Hexadecimal(str string) bool
示例:
// 数值类型(包括负数、小数)
is.Numeric(123) // true
is.Numeric(-45.67) // true
is.Numeric("123") // true
is.Numeric("abc") // false
// 纯数字(整数)
is.Number(123) // true
is.Number("123") // true
is.Number(-45) // false (负数)
is.Number("12.34") // false (小数)
// 十六进制
is.Hexadecimal("FF00AA") // true
is.Hexadecimal("123abc") // true
is.Hexadecimal("FFGG") // false (G不是十六进制)
Lowercase / Uppercase
func Lowercase(str string) bool
func Uppercase(str string) bool
示例:
// 小写
is.Lowercase("hello world") // true
is.Lowercase("Hello World") // false
// 大写
is.Uppercase("HELLO WORLD") // true
is.Uppercase("Hello World") // false
6. 颜色验证
func HEXColor(str string) bool
func RGB(str string) bool
func RGBA(str string) bool
func HSL(str string) bool
func HSLA(str string) bool
func Color(str string) bool // 支持所有颜色格式
示例:
// HEX 颜色
is.HEXColor("#FF0000") // true (红色)
is.HEXColor("#F00") // true (短格式)
is.HEXColor("#FF000080") // true (带透明度)
// RGB
is.RGB("rgb(255, 0, 0)") // true (红色)
is.RGB("rgb(255,255,255)") // true (白色)
// RGBA
is.RGBA("rgba(255, 0, 0, 0.5)") // true (半透明红色)
// HSL
is.HSL("hsl(0, 100%, 50%)") // true (红色)
// HSLA
is.HSLA("hsla(0, 100%, 50%, 0.5)") // true (半透明红色)
// 通用颜色验证
is.Color("#FF0000") // true
is.Color("rgb(255, 0, 0)") // true
is.Color("hsl(0, 100%, 50%)") // true
7. 地理坐标验证
func Latitude[T any](t T) bool
func Longitude[T any](t T) bool
说明:
- 纬度范围:-90° 到 +90°
- 经度范围:-180° 到 +180°
示例:
// 纬度
is.Latitude(45.0) // true
is.Latitude(-90.0) // true (南极)
is.Latitude("90.0") // true (北极)
is.Latitude(91.0) // false (超出范围)
// 经度
is.Longitude(120.0) // true
is.Longitude(-180.0) // true
is.Longitude("180.0") // true
is.Longitude(181.0) // false (超出范围)
8. 网络验证
IP / IPv4 / IPv6
func IP(str string) bool
func IPv4(str string) bool
func IPv6(str string) bool
示例:
// IPv4
is.IPv4("192.168.1.1") // true
is.IPv4("8.8.8.8") // true
is.IPv4("127.0.0.1") // true
is.IPv4("2001:db8::1") // false (IPv6格式)
// IPv6
is.IPv6("2001:db8::1") // true
is.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") // true
is.IP("2001:db8::1") // true
MAC - 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") // true
is.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}`) // true
is.JSON([]byte(`[1, 2, 3]`)) // true
is.JSON("invalid json") // false
is.JSON(123) // false
HTML - HTML 标签检测
func HTML(str string) bool
示例:
is.HTML("<div>content</div>") // true
is.HTML("<p>Hello World</p>") // true
is.HTML("Hello World") // false
Semver - 语义化版本
func Semver(s string) bool
说明:验证是否符合语义化版本规范 (Semantic Versioning 2.0.0),格式为 MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]。
示例:
is.Semver("1.0.0") // true
is.Semver("2.1.3-beta.2+exp.sha.5114f85") // true
is.Semver("1.0") // false (缺少PATCH)
is.Semver("v1.0.0") // false (不支持v前缀)
Label - 标签/变量名验证
func Label(s string) bool
说明:验证是否符合变量命名规范。必须以字母 (A-F) 开头,后跟字母、数字或下划线。
示例:
is.Label("API_HOST") // true
is.Label("config_debug") // true
is.Label("1INVALID") // false (以数字开头)
is.Label("api-host") // false (包含连字符)
Datetime - 日期时间验证
func Datetime(str, layout string) bool
说明:验证字符串是否匹配指定的时间格式。
示例:
is.Datetime("2023-12-25", "2006-01-02") // true
is.Datetime("10:30:45", "15:04:05") // true
is.Datetime("2023-12-25 10:30:45", time.RFC3339) // true
is.Datetime("invalid", "2006-01-02") // false
Timezone - 时区验证
func Timezone(str string) bool
说明:验证是否为有效的 IANA 时区标识符。
示例:
is.Timezone("America/New_York") // true
is.Timezone("UTC") // true
is.Timezone("Asia/Shanghai") // true
is.Timezone("Invalid/Zone") // false
10. 文件系统验证
File / Dir
func File(val any) bool
func 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) bool
func NotEmpty[T any](t T) bool
说明:检查值是否为空。空值的定义:
- 字符串、数组、切片、Map:长度为 0
- 整数、浮点数:值为 0
- 布尔值:false
- 指针、接口、通道、函数:nil
- time.Time:零值
示例:
is.Empty("") // true
is.Empty(0) // true
is.Empty(false) // true
is.Empty([]string{}) // true
is.Empty(nil) // true
is.Empty(time.Time{}) // true
is.NotEmpty("hello") // true
is.NotEmpty(42) // true
is.NotEmpty([]int{1, 2, 3}) // true
HasValue / Default
func HasValue(val any) bool
func Default(val any) bool // HasValue 的反向
说明:检查值是否不是默认静态值。
示例:
is.HasValue("hello") // true
is.HasValue(42) // true
is.HasValue(nil) // false
is.HasValue(0) // false
is.Default(0) // true
is.Default("") // true
is.Default(nil) // true
Boolean - 布尔值检查
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") // true
is.Boolean("yes") // true
is.Boolean(1) // true
is.Boolean(0) // true
is.Boolean(true) // true
is.Boolean("maybe") // false
is.Boolean(2) // false
OneOf - 候选值检查
func OneOf(val any, vals []any) bool
说明:检查值是否在允许的候选列表中。
示例:
is.OneOf("apple", []any{"apple", "banana", "orange"}) // true
is.OneOf(5, []any{1, 2, 3, 4, 5}) // true
is.OneOf("red", []any{"green", "blue"}) // false
is.OneOf("test", []any{}) // false
12. 比较验证
Compare - 通用比较
func Compare(srcVal, dstVal any, op string) bool
支持的操作符:
"=":等于"!=":不等于"<":小于"<=":小于等于">":大于">=":大于等于
示例:
is.Compare(2, 3, ">") // false
is.Compare(2, 1.3, ">") // true
is.Compare("apple", "banana", "<") // true (字典序)
is.Compare(true, false, ">") // true
is.Compare(time.Now(), time.Now().Add(-time.Hour), ">") // true
便捷比较函数
func Equal(a, b any) bool
func NotEqual(a, b any) bool
func GreaterThan(a, b any) bool
func GreaterEqualThan(a, b any) bool
func LessThan(a, b any) bool
func LessEqualThan(a, b any) bool
示例:
is.Equal(10, 10) // true
is.NotEqual(10, 5) // true
is.GreaterThan(10, 5) // true
is.GreaterEqualThan(10, 10) // true
is.LessThan(5, 10) // true
is.LessEqualThan(10, 10) // true
Between / NotBetween - 范围检查
func Between(val, min, max any) bool
func NotBetween(val, min, max any) bool
说明:检查值是否在(或不在)指定的闭区间内。要求 min < max,否则会 panic。
示例:
is.Between(5, 1, 10) // true
is.Between(10, 1, 10) // true (边界值)
is.Between(0, 1, 10) // false
is.Between("m", "a", "z") // true (字典序)
is.NotBetween(0, 1, 10) // true
is.NotBetween(11, 1, 10) // true
is.NotBetween(5, 1, 10) // false
13. 长度验证
Length - 长度比较
func Length(val any, length int, op string) bool
说明:验证值的长度是否满足指定条件。支持字符串、数组、切片、Map、通道。
示例:
is.Length("hello", 5, "=") // true
is.Length([]int{1, 2, 3}, 3, "=") // true
is.Length("world", 5, ">=") // true
is.Length("test", 5, "<") // true
is.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) // int
is.Numeric(45.67) // float64
is.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) // false
6. 比较操作的类型支持
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,否则 panic
is.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) error
func 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
}