Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom regexp validator not working properly #346

Closed
lansana opened this issue Feb 27, 2018 · 2 comments
Closed

Custom regexp validator not working properly #346

lansana opened this issue Feb 27, 2018 · 2 comments
Assignees
Labels

Comments

@lansana
Copy link

lansana commented Feb 27, 2018

Package version eg. v8, v9:

v9

Issue, Question or Enhancement:

I created a custom regexp validator, and it works for one regular expression but panics on another. I've confirmed the regular expression that paniced is a valid regular expression and works properly with my custom validator function, so I assume this is a bug with the internals of this package.

I am getting this error:

panic: Undefined validation function 'private' on field 'Visibility'

This is the validation tag that panics:

validate:"required,regexp=^(public|private|unlisted)$"

This is the working validation tag:

validate:"required,min=1,regexp=^[a-zA-Z0-9_]*$"

Code sample, to showcase or reproduce:

This is my custom validator:

func Regexp(fl validator.FieldLevel) bool {
	re := regexp.MustCompile(fl.Param())
	return re.MatchString(fl.Field().String())
}
@deankarn
Copy link
Contributor

Hey @lansana, I touch on this in the docs:

regex
	a regex validator won't be added because commas and = signs can be part
	of a regex which conflict with the validation definitions. Although
	workarounds can be made, they take away from using pure regex's.
	Furthermore it's quick and dirty but the regex's become harder to
	maintain and are not reusable, so it's as much a programming philosiphy
	as anything.

	In place of this new validator functions should be created; a regex can
	be used within the validator function and even be precompiled for better
	efficiency within regexes.go.

	And the best reason, you can submit a pull request and we can keep on
	adding to the validation library of this package!

To summarize I highly recommend you don't use a regex validator, many of the common characters used in regexes will conflict with the built-in characters when the tags are parsed; in your specific case the | is a special character that represents and or.

I have added the ability to work around such things, also in the docs:

Pipe ("|") is the 'or' validation tags separator. If you wish to have a pipe included within the parameter i.e. excludesall=| you will need to use the UTF-8 hex representation 0x7C, which is replaced in the code as a pipe, so the above will become excludesall=0x7C

type Test struct {
	Field `validate:"excludesall=|"`    // BAD! Do not include a a pipe!
	Field `validate:"excludesall=0x7C"` // GOOD! Use the UTF-8 hex representation.
}

but then regexes don't look right and so forth

I highly recommend you add a custom validation for each regex, even validator handles it this way internally:

  • the tag name will be clearer to those not as familiar with regexes
  • it will be more performant with the regex pre-compiled
  • the regexes will become reusable
  • the tags will be more readable, especially if you need a long regex, like for an email.

@deankarn deankarn self-assigned this Feb 28, 2018
@lansana
Copy link
Author

lansana commented Mar 1, 2018

Ah, thank you for the explanation. In fact, I think the approach of making custom validators per regular expression is the better way to go, because it makes things more maintainable.

I ran into the issue of having to copy/paste a regexp over to multiple validators, didn't think of the approach of adding a custom validator for a specific regular expression and referring to it by name.

Cheers!

@lansana lansana closed this as completed Mar 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants