go-ozzo/ozzo-validation
GitHub: go-ozzo/ozzo-validation
一个 Go 语言数据校验库,通过编程结构而非 struct tag 定义可配置、可扩展的校验规则,支持多种数据类型和嵌套校验。
Stars: 4117 | Forks: 244
# ozzo-validation
[](http://godoc.org/github.com/go-ozzo/ozzo-validation)
[](https://travis-ci.org/go-ozzo/ozzo-validation)
[](https://coveralls.io/github/go-ozzo/ozzo-validation?branch=master)
[](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开发, 开发工具, 开发库, 数据验证, 日志审计