在服务器上,我通过删除像这样的字符列表来清理输入。
FORBIDDEN_CHARS = %w[# % & * ( ) + = ; " , < > ? \\].freeze
'# % & * ( ) + valid = ; bit " , < > ? \\'.delete(FORBIDDEN_CHARS.join).strip.gsub(/\s{2,}/, ' ')
=> "valid bit"
我想在输入字段上使用HTML模式抢占这个。如何轻松地将此禁止字符列表转换为HTML5 pattern
属性的正则表达式?
我需要像
这样的东西pattern='[^#%&*()+=;",<>?\\]+'`
但是,pattern: "[^#{FORBIDDEN_CHARS}]+"
无法正确转义反斜杠和Firefox报告Unable to check <input pattern='[^#%&*()+=;",<>?\]+'> because the pattern is not a valid regexp: unterminated character class
。
pattern: "[^#{%w[# % & * ( ) + = ; " , < > ?].join}]+"
这可以在没有反斜杠的情况下工作,或者如果我在连接期间添加它...
pattern: "[^#{FORBIDDEN_CHARS.join}\\]+"
使用Regexp.quote
似乎逃脱了太多字符。
> "[^#{Regexp.quote FORBIDDEN_CHARS.join}\\]+"
=> "[^\\#%&\\*\\(\\)\\+=;\",<>\\?\\\\\\]+"
更新2017-08-02 我决定采用白名单模式。我现在明白HTML5模式属性是一个JavaScript正则表达式。我想获取一系列允许的符号,转义那些需要在JS正则表达式中转义的符号,并创建包含字母,数字,空格和那些符号的模式。
ALLOWED_SYMBOLS = %w[% & - : ' .]
答案 0 :(得分:1)
错误消息非常清楚,因为错误消息:
无法检查
<input pattern='[^#%&*()+=;",<>?\]+'>
,因为该模式不是有效的正则表达式:未终止的字符类
&#34;未终止的角色类&#34;意味着它正在寻找结束角色类的]
,但无法找到它。您可以看到这一点,因为您没有转义\
(\\
),而是\
]
\]
\\]
),正如你已经知道的那样Regexp.quote
它是否会正常工作。
使用
Regexp.quote
似乎逃脱了太多字符。
嗯......不。 \#
用于处理Ruby正则表达式。它不适合使用HTML5(JavaScript)模式。在前者中,# Note to future me/other developers: If you change one of the below
# lines, you *must* also change the other.
FORBIDDEN_CHARS = '#%&*()+=;",<>?\\'
ALLOWED_CHARS_PATTERN = '[#%&*()+=;",<>?\\\\]+'
起作用。在后者中,它没有。没有好办法解决这个问题。
这里的核心问题是你提出了最聪明的解决方案,而不是最好的解决方案。最好的一个是人类理解和维护的简单易行的方法。该解决方案的一半看起来像这样:
\
解决方案的另一半当然是单元测试。您的Ruby测试和浏览器测试应该在这两个测试数据中输入相同的测试数据,因此如果它们以某种不一致的方式进行更改,那么您的测试将会失败。
但是,如果你更聪明,那么你需要在JavaScript中的字符类(方括号)内转义的唯一字符是]
和FORBIDDEN_CHARS = '#%&*()+=;",<>?\\'.freeze
ALLOWED_CHARS_PATTERN = "[^#{ FORBIDDEN_CHARS.gsub(/\\/, '\\\\\0') }]+".freeze
puts ALLOWED_CHARS_PATTERN
# => [^#%&*()+=;",<>?\\]+
:
Redo
当然,您仍然需要进行单元测试。
答案 1 :(得分:0)
试试这个:
require 'sinatra'
get '/' do
FORBIDDEN_CHARS = %w[# % & * ( ) + = ; " , < > ? \\].freeze
pattern = FORBIDDEN_CHARS.join('').inspect[1..-2].gsub('\"', '"')
"<input pattern='[^#{pattern}]+' />"
end