1

在测试将嵌入式 soundcloud-track url 更改为 iframe 的方法时。转义结果时出现错误。

有人可以解释为什么在 CASE 2 中转义 +token+ 吗?我可以按原样使用结果并附加到它

下面详细介绍这两种情况。

#ruby --version
# => ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin12.2.1]

情况1

require 'cgi'

class String
  def embedda
    compiled = self
    compiled = soundcloud_replace(compiled)

    return compiled
  end

 private
  def soundcloud_replace(compiled)
    r = /(https?:\/\/(?:www.)?soundcloud.com\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*(?!\/sets(?:\/|$))(?:\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*){1,2}\/?)/i
    compiled.gsub!(r) { |match| soundcloud_player(match) }

    return compiled
  end

  def soundcloud_player(token)
    # return token # => +matched soundcloud url+ in pry
    # puts token   # => +matched soundcloud url+ in pry

    url_encoded_string = CGI::escape(token)

    # puts url_encoded_string # => +escaped matched soundcloud url+

    # "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{token}\"></iframe>"
    # => Correct interpolated string with non-encoded url

    "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{url_encoded_string}\"></iframe>"
    # => Correct interpolated string with encoded url
  end
end

案例二

require 'cgi'

class String
  def embedda
    compiled = self
    compiled = soundcloud_replace(compiled)

    return compiled
  end

 private
  def soundcloud_replace(compiled)
    compiled.gsub!(/(https?:\/\/(?:www.)?soundcloud.com\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*(?!\/sets(?:\/|$))(?:\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*){1,2}\/?)/i, soundcloud_player("\\1"))

    return compiled
  end

  def soundcloud_player(token)
    # return token # => +matched soundcloud url+  in pry
    # puts token   # => /1                        in pry

    url_encoded_string = CGI::escape(token)

    # puts url_encoded_string = CGI::escape(token) # => %5C1  in pry

    # "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{token}\"></iframe>"
    # => Correct interpolated string with non-encoded url

    "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{url_encoded_string}\"></iframe>"
    # => Interpolated string with ...?url=%5C1
  end
end
4

2 回答 2

1

在第二种情况下,您在将“\1”提供给 gsub 之前对其进行转义。转义后“url_encoded_string”包含“%5C1”。由于“\1”不存在,因此不会插入任何内容。相反,内容将替换为“url_encoded_string”的内容。

尝试以下操作,看看案例 2 的区别:

url_encoded_string = token

代替:

url_encoded_string = CGI::escape(token)
于 2013-04-10T08:59:37.600 回答
0

用于显示问题的更简单版本:

情况1:

require 'cgi'

def soundcloud_player(token)
  url_encoded_string = CGI::escape(token)
  "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{url_encoded_string}\"></iframe>"
end

soundcloud_string = "https://soundcloud.com/theeconomist/money-talks-april-8th-2013"
r = /(https?:\/\/(?:www.)?soundcloud.com\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*(?!\/sets(?:\/|$))(?:\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*){1,2}\/?)/i
soundcloud_string.gsub!(r) { |match| soundcloud_player(match) }
puts soundcloud_string.inspect
# => Correct interpolated string with encoded url:
# "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=https%3A%2F%2Fsoundcloud.com%2Ftheeconomist%2Fmoney-talks-april-8th-2013\"></iframe>"

案例二:

require 'cgi'

def soundcloud_player(token)
  url_encoded_string = CGI::escape(token)
  "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{url_encoded_string}\"></iframe>"
end

soundcloud_string = "https://soundcloud.com/theeconomist/money-talks-april-8th-2013"
soundcloud_string.gsub!(/(https?:\/\/(?:www.)?soundcloud.com\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*(?!\/sets(?:\/|$))(?:\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*){1,2}\/?)/i, soundcloud_player("\\1"))
puts soundcloud_string.inspect
# => Interpolated string with ...?url=%5C1:
# "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=%5C1\"></iframe>"
于 2013-04-09T23:54:44.627 回答