来自Ruby符号数组的HTML5输入模式
在服务器上,我通过删除这样的字符列表来清理输入来自Ruby符号数组的HTML5输入模式,ruby,regex,html,Ruby,Regex,Html,在服务器上,我通过删除这样的字符列表来清理输入 FORBIDDEN_CHARS = %w[# % & * ( ) + = ; " , < > ? \\].freeze '# % & * ( ) + valid = ; bit " , < > ? \\'.delete(FORBIDDEN_CHARS.join).strip.gsub(/\s{2,}/, ' ') => "valid bit" 但是,模式:“[^#{禁止字符数}]+”没有正确地转义
FORBIDDEN_CHARS = %w[# % & * ( ) + = ; " , < > ? \\].freeze
'# % & * ( ) + valid = ; bit " , < > ? \\'.delete(FORBIDDEN_CHARS.join).strip.gsub(/\s{2,}/, ' ')
=> "valid bit"
但是,模式:“[^#{禁止字符数}]+”
没有正确地转义反斜杠,Firefox报告无法检查,因为该模式不是有效的regexp:unterminated character类
pattern: "[^#{%w[# % & * ( ) + = ; " , < > ?].join}]+"
使用Regexp.quote
似乎转义了太多字符
> "[^#{Regexp.quote FORBIDDEN_CHARS.join}\\]+"
=> "[^\\#%&\\*\\(\\)\\+=;\",<>\\?\\\\\\]+"
试试这个:
require 'sinatra'
get '/' do
FORBIDDEN_CHARS = %w[# % & * ( ) + = ; " , < > ? \\].freeze
pattern = FORBIDDEN_CHARS.join('').inspect[1..-2].gsub('\"', '"')
"<input pattern='[^#{pattern}]+' />"
end
需要“sinatra”
获取“/”do
禁止的字符=%w[#%&*()+=;”,<>?\\]。冻结
pattern=probled\u CHARS.join(“”).inspect[1..-2].gsub(“\”,““”)
""
终止
错误信息非常清楚,错误信息如下:
无法检查
,因为模式不是有效的regexp:unterminated字符类
“Unterminated character class”表示它正在查找结束字符类的\
,但找不到它。您可以看到,这是因为没有转义的\
(\\
),而是有一个\
转义]
(\]
),您已经知道,如果这是\\]
,它将正常工作
使用Regexp.quote
似乎转义了太多字符
> "[^#{Regexp.quote FORBIDDEN_CHARS.join}\\]+"
=> "[^\\#%&\\*\\(\\)\\+=;\",<>\\?\\\\\\]+"
嗯……不。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代码?此外,您是如何生成HTML的?您是在使用Rails吗?我是在问如何正确地将Ruby正则表达式转换为HTML 5正则表达式。具体地说,如何我是否确保字符被正确转义?我正在使用Haml生成HTML。我知道我需要的正则表达式模式,但我希望能够在一个位置编辑我的禁止字符列表,并在服务器端处理的同时在视图中更新HTML模式。白名单,而不是黑名单,是输入字段的唯一安全选择。它看起来像是使用JS regex的HTML模式属性“正则表达式语言与JavaScript RegExp算法相同“-谢谢你的详细回答!我打算在我的HTML中使用白名单模式,因为这对于我的用例来说似乎更安全。JS正则表达式需要转义更多的字符@HarlemSquirrel在字符类中(方括号)?哪些字符?MDN表示\^$*+代码>是特殊的正则表达式字符。哦,等等,我现在明白了。“点(.)和星号(*)等特殊字符在字符集中并不特殊,因此它们不需要转义。”对不起,你说得对!然而,我假设连字符、方括号和反斜杠需要转义。
require 'sinatra'
get '/' do
FORBIDDEN_CHARS = %w[# % & * ( ) + = ; " , < > ? \\].freeze
pattern = FORBIDDEN_CHARS.join('').inspect[1..-2].gsub('\"', '"')
"<input pattern='[^#{pattern}]+' />"
end
# 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 = '[#%&*()+=;",<>?\\\\]+'
FORBIDDEN_CHARS = '#%&*()+=;",<>?\\'.freeze
ALLOWED_CHARS_PATTERN = "[^#{ FORBIDDEN_CHARS.gsub(/\\/, '\\\\\0') }]+".freeze
puts ALLOWED_CHARS_PATTERN
# => [^#%&*()+=;",<>?\\]+