Skip to content

Commit

Permalink
Email regex optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
nodivbyzero committed Dec 26, 2024
1 parent 6c3307e commit 2bf221f
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 2 deletions.
2 changes: 1 addition & 1 deletion regexes.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const (
rgbaRegexString = "^rgba\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
hslRegexString = "^hsl\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*\\)$"
hslaRegexString = "^hsla\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
emailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
emailRegexString = `^(?:"(?:[^"]|\\")*"|[\p{L}\p{N}\p{M}._%+-]+)@[\p{L}\p{N}\p{M}.-]+\.[\p{L}\p{M}]{2,}$`
e164RegexString = "^\\+[1-9]?[0-9]{7,14}$"
base32RegexString = "^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=|[A-Z2-7]{8})$"
base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
Expand Down
87 changes: 86 additions & 1 deletion validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8762,6 +8762,91 @@ func TestEmail(t *testing.T) {
AssertError(t, errs, "", "", "", "", "email")
}

func BenchmarkEmailValidation(b *testing.B) {
validate := New()

// Valid email test cases
validEmails := []string{
"test@mail.com",
"Dörte@Sörensen.example.com",
"θσερ@εχαμπλε.ψομ",
"юзер@екзампл.ком",
"उपयोगकर्ता@उदाहरण.कॉम",
"用户@例子.广告",
`"test test"@email.com`,
}

// Invalid email test cases
invalidEmails := []string{
"mail@domain_with_underscores.org",
"",
"test@email",
"test@email.",
"@email.com",
`"@email.com`,
}

// Define sub-benchmarks
b.Run("Valid_Emails", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, email := range validEmails {
_ = validate.Var(email, "email")
}
}
})

b.Run("Invalid_Emails", func(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, email := range invalidEmails {
_ = validate.Var(email, "email")
}
}
})

b.Run("Mixed_Types", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = validate.Var(true, "email") // Test with boolean
_ = validate.Var("test@mail.com", "email") // Test with string
}
})

// Benchmark individual cases
for _, email := range validEmails {
b.Run("Valid_"+email, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = validate.Var(email, "email")
}
})
}

for _, email := range invalidEmails {
name := email
if name == "" {
name = "Empty"
}
b.Run("Invalid_"+name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = validate.Var(email, "email")
}
})
}

// Benchmark single instance vs new validator
b.Run("Single_Validator", func(b *testing.B) {
v := New()
for i := 0; i < b.N; i++ {
_ = v.Var("test@mail.com", "email")
}
})

b.Run("New_Validator_Each_Time", func(b *testing.B) {
for i := 0; i < b.N; i++ {
v := New()
_ = v.Var("test@mail.com", "email")
}
})
}

func TestHexColor(t *testing.T) {
validate := New()

Expand Down Expand Up @@ -12080,7 +12165,7 @@ func TestExcludedIf(t *testing.T) {

test11 := struct {
Field1 bool
Field2 *string `validate:"excluded_if=Field1 false"`
Field2 *string `validate:"excluded_if=Field1 false"`
}{
Field1: false,
Field2: nil,
Expand Down

0 comments on commit 2bf221f

Please sign in to comment.