On the server I am sanitizing inputs by removing a list of characters like so.
FORBIDDEN_CHARS = %w[# % & * ( ) + = ; " , < > ? \\].freeze
'# % & * ( ) + valid = ; bit " , < > ? \\'.delete(FORBIDDEN_CHARS.join).strip.gsub(/\s{2,}/, ' ')
=> "valid bit"
I would like to preempt this with an HTML pattern on my input field. How can I easily convert this list of forbidden characters into a regular expression for the HTML5 pattern attribute?
I need something like
pattern='[^#%&*()+=;",<>?\\]+'`
However, pattern: "[^#{FORBIDDEN_CHARS}]+" does not properly escape the backslash and Firefox reports Unable to check <input pattern='[^#%&*()+=;",<>?\]+'> because the pattern is not a valid regexp: unterminated character class.
pattern: "[^#{%w[# % & * ( ) + = ; " , < > ?].join}]+"
This does work without the backslash or if I add it in during concatenation...
pattern: "[^#{FORBIDDEN_CHARS.join}\\]+"
Using Regexp.quote seems to escape too many characters.
> "[^#{Regexp.quote FORBIDDEN_CHARS.join}\\]+"
=> "[^\\#%&\\*\\(\\)\\+=;\",<>\\?\\\\\\]+"
Update 2017-08-02 I've decided to go for a whitelist pattern. I now understand that the HTML5 pattern attribute is a JavaScript regular expression. I want to take an array of allowed symbols, escape those which need to be escaped in a JS regular expression, and create the pattern that includes letters, numbers, spaces and those symbols.
ALLOWED_SYMBOLS = %w[% & - : ' .]
patternis, or how to write Ruby code that will generate that pattern?