Reputation: 745
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)?
Upvotes: 16
Views: 35669
Reputation: 626896
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.Upvotes: 17