Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails validate format with regex

In my rails app, I want to validate input on a string field containing any number of keywords (which could be more than 1 natural language word (e.g. "document number")). To recognize the individual keywords, I am entering them separated by ", " (or get their end by end of string).

For this I use

validates :keywords, presence: true, format: { with: /((\w+\s?-?\w+)(,|\z))/i, message: "please enter keywords in correct format"}

It should allow the attribute keywords (string) to contain: "word1, word2, word3 word4, word5-word6"

It should not allow the use of any other pattern. e.g. not "word1; word2;" It does incorrectly allow "word1; word2"

On rubular, this regex works; yet in my rails app it allows for example "word1; word2" or "word3; word-"

where is my error (got to say am beginner in Ruby and regex)?

like image 291
Dimitri de Ruiter Avatar asked Nov 11 '16 10:11

Dimitri de Ruiter


1 Answers

You need to use anchors \A and \z and modify the pattern to fit that logic as follows:

/\A(\w+(?:[\s-]*\w+)?)(?:,\s*\g<1>)*\z/

See the Rubular demo

Details:

  • \A - start of string
  • (\w+(?:[\s-]*\w+)?) - Group 1 capturing:
    • \w+ - 1 or more word chars
    • (?:[\s-]*\w+)? - 1 or 0 sequences of:
      • [\s-]* - 0+ whitespaces or -
      • \w+ - 1 or more word chars
  • (?:,\s*\g<1>)* - 0 or more sequences of:
    • ,\s* - comma and 0+ whitespaces
    • \g<1> - the same pattern as in Group 1
  • \z - end of string.
like image 93
Wiktor Stribiżew Avatar answered Oct 15 '22 20:10

Wiktor Stribiżew