go-ozzo/ozzo-validation

GitHub: go-ozzo/ozzo-validation

一个 Go 语言数据校验库,通过编程结构而非 struct tag 定义可配置、可扩展的校验规则,支持多种数据类型和嵌套校验。

Stars: 4117 | Forks: 244

# ozzo-validation [![GoDoc](https://godoc.org/github.com/go-ozzo/ozzo-validation?status.png)](http://godoc.org/github.com/go-ozzo/ozzo-validation) [![Build Status](https://travis-ci.org/go-ozzo/ozzo-validation.svg?branch=master)](https://travis-ci.org/go-ozzo/ozzo-validation) [![Coverage Status](https://coveralls.io/repos/github/go-ozzo/ozzo-validation/badge.svg?branch=master)](https://coveralls.io/github/go-ozzo/ozzo-validation?branch=master) [![Go Report](https://goreportcard.com/badge/github.com/go-ozzo/ozzo-validation)](https://goreportcard.com/report/github.com/go-ozzo/ozzo-validation) ## 描述 ozzo-validation 是一个 Go 包,提供可配置且可扩展的数据校验功能。 它具有以下特点: * 使用正常的编程结构而不是容易出错的 struct tag 来指定如何校验数据。 * 可以校验不同类型的数据,例如 struct、字符串、字节切片、切片、map、数组。 * 可以校验自定义数据类型,只要它们实现了 `Validatable` 接口。 * 可以校验实现了 `sql.Valuer` 接口的数据类型(例如 `sql.NullString`)。 * 可自定义且格式良好的校验错误。 * 支持 error code 和消息翻译。 * 提供了丰富的开箱即用的校验规则。 * 极其容易创建和使用自定义校验规则。 有关此库如何在应用程序中使用的示例,请参阅 [go-rest-api](https://github.com/qiangxue/go-rest-api),它是一个用于构建 RESTful API 的 Go 起始套件。 ## 环境要求 Go 1.13 或更高版本。 ## 快速入门 ozzo-validation 包主要包含一组校验规则和两个校验方法。你使用 校验规则来描述一个值如何才被认为是有效的,然后你可以调用 `validation.Validate()` 或 `validation.ValidateStruct()` 来校验该值。 ### 安装 运行以下命令来安装该包: ``` go get github.com/go-ozzo/ozzo-validation ``` ### 校验简单的值 对于简单的值,例如字符串或整数,你可以使用 `validation.Validate()` 来校验它。例如, ``` package main import ( "fmt" "github.com/go-ozzo/ozzo-validation/v4" "github.com/go-ozzo/ozzo-validation/v4/is" ) func main() { data := "example" err := validation.Validate(data, validation.Required, // not empty validation.Length(5, 100), // length between 5 and 100 is.URL, // is a valid URL ) fmt.Println(err) // Output: // must be a valid URL } ``` 方法 `validation.Validate()` 将按照列出的顺序依次执行规则。如果某个规则未通过 校验,该方法将返回相应的错误并跳过其余的规则。如果该值通过了所有的校验规则, 该方法将返回 nil。 ### 校验 Struct 对于 struct 值,你通常想要检查其字段是否有效。例如,在一个 RESTful 应用程序中,你 可能会将请求 payload 反序列化为一个 struct,然后校验该 struct 的字段。如果一个或多个字段 无效,你可能希望得到一个错误,描述哪些字段是无效的。你可以使用 `validation.ValidateStruct()` 来实现此目的。一个 struct 可以为多个字段指定规则,并且一个字段可以关联多个 规则。例如, ``` type Address struct { Street string City string State string Zip string } func (a Address) Validate() error { return validation.ValidateStruct(&a, // Street cannot be empty, and the length must between 5 and 50 validation.Field(&a.Street, validation.Required, validation.Length(5, 50)), // City cannot be empty, and the length must between 5 and 50 validation.Field(&a.City, validation.Required, validation.Length(5, 50)), // State cannot be empty, and must be a string consisting of two letters in upper case validation.Field(&a.State, validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))), // State cannot be empty, and must be a string consisting of five digits validation.Field(&a.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), ) } a := Address{ Street: "123", City: "Unknown", State: "Virginia", Zip: "12345", } err := a.Validate() fmt.Println(err) // Output: // Street: the length must be between 5 and 50; State: must be in a valid format. ``` 请注意,当调用 `validation.ValidateStruct` 来校验 struct 时,你应该向该方法传递指向该 struct 的 指针,而不是 struct 本身。同样,当调用 `validation.Field` 为 struct 字段指定规则时,你应该使用指向该 struct 字段的指针。 当执行 struct 校验时,字段将按照它们在 `ValidateStruct` 中指定的顺序进行校验。 并且当校验每个字段时,其规则也会按照它们与该字段关联的顺序进行评估。 如果某个规则失败,将为该字段记录一个错误,并且校验将继续处理下一个字段。 ### 校验 Map 有时你可能需要处理存储在 map 中的动态数据,而不是类型化的 model。在这种情况下你可以使用 `validation.Map()`。 一个 map 可以为多个 key 指定规则,并且一个 key 可以关联多个 规则。例如, ``` c := map[string]interface{}{ "Name": "Qiang Xue", "Email": "q", "Address": map[string]interface{}{ "Street": "123", "City": "Unknown", "State": "Virginia", "Zip": "12345", }, } err := validation.Validate(c, validation.Map( // Name cannot be empty, and the length must be between 5 and 20. validation.Key("Name", validation.Required, validation.Length(5, 20)), // Email cannot be empty and should be in a valid email format. validation.Key("Email", validation.Required, is.Email), // Validate Address using its own validation rules validation.Key("Address", validation.Map( // Street cannot be empty, and the length must between 5 and 50 validation.Key("Street", validation.Required, validation.Length(5, 50)), // City cannot be empty, and the length must between 5 and 50 validation.Key("City", validation.Required, validation.Length(5, 50)), // State cannot be empty, and must be a string consisting of two letters in upper case validation.Key("State", validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))), // State cannot be empty, and must be a string consisting of five digits validation.Key("Zip", validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), )), ), ) fmt.Println(err) // Output: // Address: (State: must be in a valid format; Street: the length must be between 5 and 50.); Email: must be a valid email address. ``` 当执行 map 校验时,key 将按照它们在 `Map` 中指定的顺序进行校验。 并且当校验每个 key 时,其规则也会按照它们与该 key 关联的顺序进行评估。 如果某个规则失败,将为该 key 记录一个错误,并且校验将继续处理下一个 key。 ### 校验错误 `validation.ValidateStruct` 方法以 `validation.Errors` 的形式返回在 struct 字段中发现的校验错误, 它是一个由字段及其对应错误组成的 map。如果校验通过,则返回 nil。 默认情况下,`validation.Errors` 使用名为 `json` 的 struct tag 来确定应该使用哪些名称 来表示无效的字段。该类型还实现了 `json.Marshaler` 接口,因此可以将其序列化 为适当的 JSON 对象。例如, ``` type Address struct { Street string `json:"street"` City string `json:"city"` State string `json:"state"` Zip string `json:"zip"` } // ...perform validation here... err := a.Validate() b, _ := json.Marshal(err) fmt.Println(string(b)) // Output: // {"street":"the length must be between 5 and 50","state":"must be in a valid format"} ``` 你可以修改 `validation.ErrorTag` 以使用不同的 struct tag 名称。 如果你不喜欢 `ValidateStruct` 根据 struct 字段名称或相应的 tag 值确定错误 key 的这种魔法行为, 你可以使用以下替代方法: ``` c := Customer{ Name: "Qiang Xue", Email: "q", Address: Address{ State: "Virginia", }, } err := validation.Errors{ "name": validation.Validate(c.Name, validation.Required, validation.Length(5, 20)), "email": validation.Validate(c.Name, validation.Required, is.Email), "zip": validation.Validate(c.Address.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))), }.Filter() fmt.Println(err) // Output: // email: must be a valid email address; zip: cannot be blank. ``` 在上面的例子中,我们通过一系列名称和相应的校验结果构建了一个 `validation.Errors`。 最后我们调用 `Errors.Filter()` 来从 `Errors` 中移除所有对应于成功校验结果的 nil 值。 如果 `Errors` 为空,该方法将返回 nil。 上述方法非常灵活,因为它允许你自由地构建校验错误结构。你可以 使用它来校验 struct 和非 struct 值。与使用 `ValidateStruct` 校验 struct 相比, 它的缺点是你必须冗余地指定错误 key,而 `ValidateStruct` 可以自动 找到它们。 ### 内部错误 内部错误不同于校验错误,内部错误是由代码故障引起的(例如 一个 validator 进行远程调用以校验某些数据时,远程服务却宕机了),而不是 被校验的数据引起的。当在数据校验期间发生内部错误时,你可以允许用户重新提交 相同的数据以再次执行校验,期望程序恢复功能。另一方面,如果数据校验 由于数据错误而失败,用户通常不应再次重新提交相同的数据。 为了区分内部错误和校验错误,当 validator 中发生内部错误时,通过调用 `validation.NewInternalError()` 将其包装成 `validation.InternalError`。然后 validator 的用户可以检查 返回的错误是否是内部错误。例如, ``` if err := a.Validate(); err != nil { if e, ok := err.(validation.InternalError); ok { // an internal error happened fmt.Println(e.InternalError()) } } ``` ## 可校验类型 如果一个类型实现了 `validation.Validatable` 接口,那么它就是可校验的。 当使用 `validation.Validate` 来校验一个可校验的值时,如果没有发现关于 给定校验规则的错误,它会进一步调用该值的 `Validate()` 方法。 同样,当 `validation.ValidateStruct` 正在校验一个其类型为可校验的 struct 字段时,在它通过了列出的规则后,它将调用 该字段的 `Validate` 方法。 在下面的示例中,`Customer` 的 `Address` 字段是可校验的,因为 `Address` 实现了 `validation.Validatable`。因此,当使用 `validation.ValidateStruct` 校验 `Customer` struct 时, 校验将“深入”到 `Address` 字段中。 ``` type Customer struct { Name string Gender string Email string Address Address } func (c Customer) Validate() error { return validation.ValidateStruct(&c, // Name cannot be empty, and the length must be between 5 and 20. validation.Field(&c.Name, validation.Required, validation.Length(5, 20)), // Gender is optional, and should be either "Female" or "Male". validation.Field(&c.Gender, validation.In("Female", "Male")), // Email cannot be empty and should be in a valid email format. validation.Field(&c.Email, validation.Required, is.Email), // Validate Address using its own validation rules validation.Field(&c.Address), ) } c := Customer{ Name: "Qiang Xue", Email: "q", Address: Address{ Street: "123 Main Street", City: "Unknown", State: "Virginia", Zip: "12345", }, } err := c.Validate() fmt.Println(err) // Output: // Address: (State: must be in a valid format.); Email: must be a valid email address. ``` 有时,你可能想要跳过对某个类型的 `Validate` 方法的调用。为此,只需将 `validation.Skip` 规则与被校验的值关联起来即可。 ### 可校验类型的 Map/切片/数组 当校验一个元素类型实现了 `validation.Validatable` 接口的迭代对象(map、切片或数组)时, `validation.Validate` 方法将调用每一个非 nil 元素的 `Validate` 方法。 这些元素的校验错误将作为 `validation.Errors` 返回,它将无效元素的 key 映射到其对应的校验错误。例如, ``` addresses := []Address{ Address{State: "MD", Zip: "12345"}, Address{Street: "123 Main St", City: "Vienna", State: "VA", Zip: "12345"}, Address{City: "Unknown", State: "NC", Zip: "123"}, } err := validation.Validate(addresses) fmt.Println(err) // Output: // 0: (City: cannot be blank; Street: cannot be blank.); 2: (Street: cannot be blank; Zip: must be in a valid format.). ``` 当使用 `validation.ValidateStruct` 来校验 struct 时,上述校验过程也适用于那些 是可校验类型的 map/切片/数组的 struct 字段。 #### Each `Each` 校验规则允许你将一组规则应用于数组、切片或 map 的每个元素。 ``` type Customer struct { Name string Emails []string } func (c Customer) Validate() error { return validation.ValidateStruct(&c, // Name cannot be empty, and the length must be between 5 and 20. validation.Field(&c.Name, validation.Required, validation.Length(5, 20)), // Emails are optional, but if given must be valid. validation.Field(&c.Emails, validation.Each(is.Email)), ) } c := Customer{ Name: "Qiang Xue", Emails: []Email{ "valid@example.com", "invalid", }, } err := c.Validate() fmt.Println(err) // Output: // Emails: (1: must be a valid email address.). ``` ### 指针 当被校验的值是一个指针时,大多数校验规则会校验指针指向的实际值。 如果指针为 nil,这些规则将跳过校验。 `validation.Required` 和 `validation.NotNil` 规则是个例外。当指针为 nil 时,它们 将报告校验错误。 ### 实现 `sql.Valuer` 的类型 如果数据类型实现了 `sql.Valuer` 接口(例如 `sql.NullString`),内置的校验规则将正确处理 它。特别是,当规则校验此类数据时,它会调用 `Value()` 方法并校验 返回的值。 ### Required 与 Not Nil 在校验输入值时,关于检查输入值是否已提供,有两种不同的场景。 在第一种场景中,如果输入值未被输入或输入为零值(例如 空字符串、零整数),则认为输入值缺失。在这种情况下你可以使用 `validation.Required` 规则。 在第二种场景中,只有当输入值未被输入时才认为它缺失。在这种情况下通常使用 指针字段,以便你可以通过检查指针是否为 nil 来检测值是否已输入。 你可以使用 `validation.NotNil` 规则来确保输入了一个值(即使它是一个零值)。 ### 嵌入 Struct `validation.ValidateStruct` 方法将正确校验包含嵌入 struct 的 struct。特别是, 嵌入 struct 的字段被视为直接属于包含它的 struct。例如, ``` type Employee struct { Name string } type Manager struct { Employee Level int } m := Manager{} err := validation.ValidateStruct(&m, validation.Field(&m.Name, validation.Required), validation.Field(&m.Level, validation.Required), ) fmt.Println(err) // Output: // Level: cannot be blank; Name: cannot be blank. ``` 在上面的代码中,我们使用 `&m.Name` 来指定对嵌入 struct `Employee` 的 `Name` 字段的校验。 并且校验错误使用 `Name` 作为与 `Name` 字段相关的错误的 key,就像 `Name` 是直接 属于 `Manager` 的字段一样。 如果 `Employee` 实现了 `validation.Validatable` 接口,我们也可以使用以下代码来校验 `Manager`,这会生成相同的校验结果: ``` func (e Employee) Validate() error { return validation.ValidateStruct(&e, validation.Field(&e.Name, validation.Required), ) } err := validation.ValidateStruct(&m, validation.Field(&m.Employee), validation.Field(&m.Level, validation.Required), ) fmt.Println(err) // Output: // Level: cannot be blank; Name: cannot be blank. ``` ### 条件校验 有时,我们可能只想在满足特定条件时校验一个值。例如,我们想要确保 仅在 `quantity` 字段不为空时,`unit` struct 字段才不为空;或者我们可能想要确保提供了 `email` 或 `phone`。这种所谓的条件校验可以借助 `validation.When` 来实现。 以下代码实现了上述示例: ``` result := validation.ValidateStruct(&a, validation.Field(&a.Unit, validation.When(a.Quantity != "", validation.Required).Else(validation.Nil)), validation.Field(&a.Phone, validation.When(a.Email == "", validation.Required.Error('Either phone or Email is required.')), validation.Field(&a.Email, validation.When(a.Phone == "", validation.Required.Error('Either phone or Email is required.')), ) ``` 请注意,`validation.When` 和 `validation.When.Else` 可以接受一系列校验规则。这些规则仅在条件为 true 时 执行,或在条件为 false 时 执行。 上面的代码也可以使用快捷方式 `validation.Required.When` 来简化: ``` result := validation.ValidateStruct(&a, validation.Field(&a.Unit, validation.Required.When(a.Quantity != ""), validation.Nil.When(a.Quantity == "")), validation.Field(&a.Phone, validation.Required.When(a.Email == "").Error('Either phone or Email is required.')), validation.Field(&a.Email, validation.Required.When(a.Phone == "").Error('Either phone or Email is required.')), ) ``` ### 自定义错误消息 所有内置的校验规则都允许你自定义其错误消息。为此,只需调用规则的 `Error()` 方法。例如, ``` data := "2123" err := validation.Validate(data, validation.Required.Error("is required"), validation.Match(regexp.MustCompile("^[0-9]{5}$")).Error("must be a string with five digits"), ) fmt.Println(err) // Output: // must be a string with five digits ``` 你也可以自定义内置规则的预定义错误,从而使自定义应用于该规则的*每一个* 实例。例如,`Required` 规则使用预定义错误 `ErrRequired`。你可以在 应用程序初始化期间自定义它: ``` validation.ErrRequired = validation.ErrRequired.SetMessage("the value is required") ``` ### Error Code 和消息翻译 校验规则返回的错误实现了 `Error` 接口,该接口包含 `Code()` 方法 以提供 error code 信息。虽然校验错误的消息通常是自定义的,但 code 是不可变的。 你可以使用 error code 以编程方式检查校验错误,或查找相应消息的翻译。 如果你正在开发自己的校验规则,你可以使用 `validation.NewError()` 来创建一个校验错误,该错误 实现了上述 `Error` 接口。 ## 创建自定义规则 创建自定义规则就像实现 `validation.Rule` 接口一样简单。该接口包含一个 如下所示的方法,该校验值并返回校验错误(如果有): ``` // Validate validates a value and returns an error if validation fails. Validate(value interface{}) error ``` 如果你已经有了一个具有如上所示相同签名的函数,你可以调用 `validation.By()` 将 其转换为一个校验规则。例如, ``` func checkAbc(value interface{}) error { s, _ := value.(string) if s != "abc" { return errors.New("must be abc") } return nil } err := validation.Validate("xyz", validation.By(checkAbc)) fmt.Println(err) // Output: must be abc ``` 如果你的校验函数接受额外的参数,你可以使用以下闭包技巧: ``` func stringEquals(str string) validation.RuleFunc { return func(value interface{}) error { s, _ := value.(string) if s != str { return errors.New("unexpected string") } return nil } } err := validation.Validate("xyz", validation.By(stringEquals("abc"))) fmt.Println(err) // Output: unexpected string ``` ### 规则组 当多个规则的组合在多个地方使用时,你可以使用以下技巧来创建一个 规则组,从而使你的代码更易于维护。 ``` var NameRule = []validation.Rule{ validation.Required, validation.Length(5, 20), } type User struct { FirstName string LastName string } func (u User) Validate() error { return validation.ValidateStruct(&u, validation.Field(&u.FirstName, NameRule...), validation.Field(&u.LastName, NameRule...), ) } ``` 在上面的示例中,我们创建了一个由两个校验规则组成的规则组 `NameRule`。然后我们使用这个规则 组来校验 `FirstName` 和 `LastName`。 ## 上下文感知的校验 虽然大多数校验规则都是独立的,但某些规则可能动态依赖于上下文。规则可以实现 `validation.RuleWithContext` 接口来支持所谓的上下文感知校验。 要使用上下文校验任意值,请调用 `validation.ValidateWithContext()`。`context.Conext` 参数 将被传递给那些实现了 `validation.RuleWithContext` 的规则。 要使用上下文校验 struct 的字段,请调用 `validation.ValidateStructWithContext()`。 你可以通过同时实现 `validation.Rule` 和 `validation.RuleWithContext` 从头开始定义上下文感知的规则。 你也可以使用 `validation.WithContext()` 将函数转换为上下文感知规则。例如, ``` rule := validation.WithContext(func(ctx context.Context, value interface{}) error { if ctx.Value("secret") == value.(string) { return nil } return errors.New("value incorrect") }) value := "xyz" ctx := context.WithValue(context.Background(), "secret", "example") err := validation.ValidateWithContext(ctx, value, rule) fmt.Println(err) // Output: value incorrect ``` 在执行上下文感知校验时,如果规则没有实现 `validation.RuleWithContext`,则会 改用其 `validation.Rule`。 ## 内置校验规则 `validation` 包中提供了以下规则: * `In(...interface{})`:检查是否可以在给定的值列表中找到某个值。 * `NotIn(...interface{})`:检查某个值是否不在给定的值列表中。 * `Length(min, max int)`:检查值的长度是否在指定范围内。 此规则只能用于校验字符串、切片、map 和数组。 * `RuneLength(min, max int)`:检查字符串的长度是否在指定范围内。 此规则类似于 `Length`,不同之处在于当被校验的值是字符串时,它检查 其 长度而不是字节长度。 * `Min(min interface{})` 和 `Max(max interface{})`:检查值是否在指定范围内。 这两个规则只能用于校验 int、uint、float 和 time.Time 类型。 * `Match(*regexp.Regexp)`:检查值是否匹配指定的正则表达式。 此规则只能用于字符串和字节切片。 * `Date(layout string)`:检查字符串值是否是格式由 layout 指定的日期。 通过调用 `Min()` 和/或 `Max()`,你可以额外检查该日期是否在指定范围内。 * `Required`:检查值是否不为空(既不是 nil 也不是零值)。 * `NotNil`:检查指针值是否不为 nil。非指针值被视为有效。 * `NilOrNotEmpty`:检查值是 nil 指针还是非空值。这与 `Required` 的不同之处在于它将 nil 指针视为有效。 * `Nil`:检查值是否为 nil 指针。 * `Empty`:检查值是否为空。nil 指针被视为有效。 * `Skip`:这是一个特殊的规则,用于指示应跳过它之后的所有规则(包括嵌套规则)。 * `MultipleOf`:检查值是否是指定范围的倍数。 * `Each(rules ...Rule)`:使用其他规则检查迭代对象(map/切片/数组)中的元素。 * `When(condition, rules ...Rule)`:仅当条件为 true 时使用指定规则进行校验。 * `Else(rules ...Rule)`:必须与 `When(condition, rules ...Rule)` 一起使用,仅当条件为 false 时使用指定规则进行校验。 `is` 子包提供了一系列常用的字符串校验规则,可用于检查值的格式 是否满足某些要求。请注意,这些规则只处理字符串和字节切片,如果字符串 或字节切片为空,则被视为有效。你可以使用 `Required` 规则来确保值不为空。 以下是 `is` 包提供的所有规则的完整列表: * `Email`:校验字符串是否为 email。它还会检查 email 域名是否存在 MX 记录。 * `EmailFormat`:校验字符串是否为 email。它不会检查 MX 记录是否存在。 * `URL`:校验字符串是否为有效的 URL * `RequestURL`:校验字符串是否为有效的请求 URL * `RequestURI`:校验字符串是否为有效的请求 URI * `Alpha`:校验字符串是否仅包含英文字母 (a-zA-Z) * `Digit`:校验字符串是否仅包含数字 (0-9) * `Alphanumeric`:校验字符串是否仅包含英文字母和数字 (a-zA-Z0-9) * `UTFLetter`:校验字符串是否仅包含 unicode 字母 * `UTFDigit`:校验字符串是否仅包含 unicode 十进制数字 * `UTFLetterNumeric`:校验字符串是否仅包含 unicode 字母和数字 * `UTFNumeric`:校验字符串是否仅包含 unicode 数字字符(类别 N) * `LowerCase`:校验字符串是否仅包含小写 unicode 字母 * `UpperCase`:校验字符串是否仅包含大写 unicode 字母 * `Hexadecimal`:校验字符串是否为有效的十六进制数字 * `HexColor`:校验字符串是否为有效的十六进制颜色代码 * `RGBColor`:校验字符串是否为 rgb(R, G, B) 格式的有效 RGB 颜色 * `Int`:校验字符串是否为有效的整数 * `Float`:校验字符串是否为浮点数 * `UUIDv3`:校验字符串是否为有效的 version 3 UUID * `UUIDv4`:校验字符串是否为有效的 version 4 UUID * `UUIDv5`:校验字符串是否为有效的 version 5 UUID * `UUID`:校验字符串是否为有效的 UUID * `CreditCard`:校验字符串是否为有效的信用卡号 * `ISBN10`:校验字符串是否为 ISBN version 10 * `ISBN13`:校验字符串是否为 ISBN version 13 * `ISBN`:校验字符串是否为 ISBN(version 10 或 13) * `JSON`:校验字符串是否为有效的 JSON 格式 * `ASCII`:校验字符串是否仅包含 ASCII 字符 * `PrintableASCII`:校验字符串是否仅包含可打印的 ASCII 字符 * `Multibyte`:校验字符串是否包含多字节字符 * `FullWidth`:校验字符串是否包含全角字符 * `HalfWidth`:校验字符串是否包含半角字符 * `VariableWidth`:校验字符串是否同时包含全角和半角字符 * `Base64`:校验字符串是否以 Base64 编码 * `DataURI`:校验字符串是否为有效的 base64 编码数据 URI * `E164`:校验字符串是否为有效的 E164 电话号码 (+19251232233) * `CountryCode2`:校验字符串是否为有效的 ISO3166 Alpha 2 国家代码 * `CountryCode3`:校验字符串是否为有效的 ISO3166 Alpha 3 国家代码 * `DialString`:校验字符串是否为可以传递给 Dial() 的有效拨号字符串 * `MAC`:校验字符串是否为 MAC 地址 * `IP`:校验字符串是否为有效的 IP 地址(version 4 或 6) * `IPv4`:校验字符串是否为有效的 version 4 IP 地址 * `IPv6`:校验字符串是否为有效的 version 6 IP 地址 * `Subdomain`:校验字符串是否为有效的子域 * `Domain`:校验字符串是否为有效的域名 * `DNSName`:校验字符串是否为有效的 DNS 名称 * `Host`:校验字符串是否为有效的 IP(v4 和 v6)或有效的 DNS 名称 * `Port`:校验字符串是否为有效的端口号 * `MongoID`:校验字符串是否为有效的 Mongo ID * `Latitude`:校验字符串是否为有效的纬度 * `Longitude`:校验字符串是否为有效的经度 * `SSN`:校验字符串是否为社会保障号 (SSN) * `Semver`:校验字符串是否为有效的语义化版本
标签:EVTX分析, Go, Ruby工具, SOC Prime, Syscall, Web开发, 开发工具, 开发库, 数据验证, 日志审计