我有3个字符串:
#1 アンジェリーナ・ジョリー
#2 %E3%82%A2%E3%83%B3%E3%82%B8%E3%82%A7%E3%83%AA%E3%83%BC%E3%83%8A%E3%83%BB%E3%82%B8%E3%83%A7%E3%83%AA%E3%83%BC
#3 Angelina_Jolie
CGI.escape
(来自Ruby或任何其他执行相同操作的方法)是否已应用于给定字符串? CGI.escape
应用于字符串,结果将会与原始字符串不同?在这种情况下,#1可以转义,而#3则不转义。答案 0 :(得分:1)
鉴于
irb(main):001:0> require 'cgi'
=> true
和
irb(main):002:0> x = "アンジェリーナ・ジョリー"
irb(main):003:0> y = "%E3%82%A2%E3%83%B3%E3%82%B8%E3%82%A7%E3%83%AA%E3%83%BC%E3%83%8A%E3%83%BB%E3%82%B8%E3%83%A7%E3%83%AA%E3%83%BC"
irb(main):005:0> z = "Angelina_Jolie"
要告知字符串已经转义一次,请将字符串与其未转义的值进行比较:
irb(main):141:0> x == CGI::unescape(x)
=> true
irb(main):142:0> y == CGI::unescape(y)
=> false
irb(main):143:0> z == CGI::unescape(z)
=> true
您可以在此处看到y == CGI::unescape(y)
返回false
。只要您确定字符串中的转义字符是由CGI::escape
的应用程序引起的,它应该为您提供所需的答案。我相信这回答了你的第一个问题。
如果字符串可以/应该被转义,那么将在以下比较中返回false
:
irb(main):017:0> CGI::escape(CGI::unescape(x)) == CGI::unescape(CGI::escape(x))
=> false
irb(main):018:0> CGI::escape(CGI::unescape(y)) == CGI::unescape(CGI::escape(y))
=> true
irb(main):019:0> CGI::escape(CGI::unescape(z)) == CGI::unescape(CGI::escape(z))
=> true
在我的回答中没有上面的第一步,这不允许您区分类型y
和类型z
,也就是说,您无法告诉y
1}}已被转义且z
从未需要它,但至少你知道你不需要再次应用转义。我认为这是你第二个问题的答案。
答案 1 :(得分:1)
确定是否应该通过转义字符串来转义字符串也没有价值。
唯一的情况是,如果没有任何东西可以逃脱,则不会通过转义字符串来更改字符串。在这种情况下,再次逃离的成本可以忽略不计:
CGI.escape(CGI.escape(CGI.escape('foo'))) == 'foo'
如果有东西可以逃脱,通过逃避添加的字符本身就可以逃脱:
CGI.escape('<b>foo</b>') == "%3Cb%3Efoo%3C%2Fb%3E"
CGI.escape(CGI.escape('<b>foo</b>')) == "%253Cb%253Efoo%253C%252Fb%253E"
CGI.escape(CGI.escape(CGI.escape('<b>foo</b>'))) == '%25253Cb%25253Efoo%25253C%25252Fb%25253E'
再次逃避并不会区分可以转义但尚未转义的内容,而是可以转义且已经转义的内容。
我认为这是确保你只逃避一次的唯一解决办法。
答案 2 :(得分:0)
一种方法是假设如果字符串包含除转义序列以外的可逃避字符,则需要对其进行转义。例如,%3E
不需要转义,但%3E>
应转义为%253E%3E
。您可以通过在转义和重新转义后将字符串与自身进行比较来检查此类字符:
def CGI.maybe_escape str
return str if str == escape(unescape(str))
escape str
end
CGI.maybe_escape('>')
# "%3E"
CGI.maybe_escape(CGI.maybe_escape('%3E>'))
# "%253E%3E" <-- only escapes once!