validator icon indicating copy to clipboard operation
validator copied to clipboard

Efficient Regex Validation Integration

Open yousifnimah opened this issue 2 years ago • 5 comments

Enhances

This pull request introduces an optimized version of the code that enables the validation of field values using custom regex patterns specified through tags. The improvements made to the code enhance efficiency, readability, and flexibility. The custom regex patterns can be easily associated with fields using tags, allowing for seamless validation based on specific requirements.

Here's a summary of the changes made:

  • The regular expression pattern is retrieved from the validation tag parameter using fl.Param().
  • The pattern is then compiled into a regular expression object using regexp.Compile
  • If there is an error during compilation, a panic is triggered, providing information about the field type that caused the error.
  • The field value is obtained as a string using fl.Field().String().
  • The regular expression object is used to match the field value string, and true is returned if there is a match, indicating the field value is valid according to the regular expression.
  • These modifications improve the function's reliability and readability, ensuring that errors during regular expression compilation are appropriately handled.
  • An example file that provides detailed usage instructions.

Example of usage:

type User struct {
	Email string `validate:"required,email"`
	Phone string `validate:"required,regex=^[0-9]{10}$"`
}

yousifnimah avatar Jun 14 '23 19:06 yousifnimah

Coverage Status

coverage: 73.926% (-0.05%) from 73.972% when pulling 794024fdcb9976e838958eb3d99c5f2f29a2d057 on yousifnimah:master into bd1113d5c1901c5205fc0a7af031a11268ff13ee on go-playground:master.

coveralls avatar Jun 14 '23 19:06 coveralls

I will need to think about this, again, as in the documentation I explicitly state why I do not already have a regex validation, but to summarize a few points:

  • Hard to make translations on regex tag which can literally be anything and or multiple things at once.
  • Valid Regex characters WILL conflict with the tags parsing such as ,(COMMA) and will have to somehow be escaped.
  • Regexes often get long or messy fast which cluster the code reading in a tag
  • Fixing a bad regex definition is hard, you must go around everywhere it's been duplicated whereas defining behind a tag only the has to be fixed in one place and update the imported lib, if any, only.

deankarn avatar Aug 06 '23 17:08 deankarn

Thank you for your response.

I have inspired this validation from Laravel regex validation and as developers we occasionally need to validate based on regex pattern, for example: validating custom date format or the country code.

Furthermore, regarding translation message I have added a general message for all supported languages which is "invalid format" and this message returns for any invalid case. We can pass a custom message from the definition of regex as a tag field.

However, I would like to contribute with this library and help to develop new features.

yousifnimah avatar Aug 06 '23 17:08 yousifnimah

@yousifnimah yep I understand and makes sense.

You can also do this today by registering a custom validation with tag that uses the Regex internals which may be more maintainable.

How do you propose to deal with the conflicting characters?

deankarn avatar Aug 06 '23 19:08 deankarn

@yousifnimah yep I understand and makes sense.

You can also do this today by registering a custom validation with tag that uses the Regex internals which may be more maintainable.

How do you propose to deal with the conflicting characters?

I've added a handler for comma representation and it would be like this:

// Replace any escaped backslashes before commas with a placeholder to avoid escaping.
// We'll replace them back later after compiling the regex pattern.
regexPattern = strings.ReplaceAll(regexPattern, `__comma__`, ",")

The usage in the struct tag:

Phone string `validate:"required,regex=^__comma__[0-9]{2}$"`

It represents this pattern:

Phone string `validate:"required,regex=^\,[0-9]{2}$"`

And it works fine.

yousifnimah avatar Aug 06 '23 20:08 yousifnimah