检查字符串是否已转义

我有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 
  1. 如何从其他字符串中识别#2,换句话说,如何检查方法CGI.escape (来自Ruby或任何其他执行相同操作的方法)是否已应用于给定字符串?
  2. 如何轻松检查字符串是否应该被转义,换句话说,如果将CGI.escape应用于字符串,结果将与原始字符串不同? 在这种情况下,#1可以转义,而#3则不转义。

一种方法是假设如果字符串包含除转义序列之外的可转义字符,则需要对其进行转义。 例如, %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! 

通过字符串是否可以转义来识别是否应该转义字符串没有任何价值。

通过转义字符串不会更改字符串的唯一情况是,如果没有任何东西可以逃脱。 在这种情况下,再次逃离的成本可以忽略不计:

 CGI.escape(CGI.escape(CGI.escape('foo'))) == 'foo' 

如果有东西要逃脱,通过转义添加的字符本身就可以逃脱:

 CGI.escape('foo') == "%3Cb%3Efoo%3C%2Fb%3E" CGI.escape(CGI.escape('foo')) == "%253Cb%253Efoo%253C%252Fb%253E" CGI.escape(CGI.escape(CGI.escape('foo'))) == '%25253Cb%25253Efoo%25253C%25252Fb%25253E' 

因此,再次转义并不会区分可以转义但尚未转义的内容,而是可以转义且已经转义的内容。

我认为唯一可以解决的问题是确保你只逃脱一次。

特定

 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已经被转义并且z从不需要它,但至少你知道你不需要再次申请逃生。 我认为这是你第二个问题的答案。