如何使单引号字符串像 Ruby 中的双引号字符串一样?

How to make a single-quoted string act like a double-quoted string in Ruby?

我有一个包含 HTMl 代码的文件,HTML 标签的编码如下:

\x3cdiv data-name\x3d\x22region-name\x22 class\x3d\x22main-id\x22\x3eUK\x3c/div\x3e

解码后的HTML应该是:

<div data-name="region-name" class="main-id">UK</div>

在 Ruby 中,我使用 cgi 库到 unescapeHTML 但是它不起作用,因为当它读取内容时它不识别编码标签,这是另一个例子:

require 'cgi'

single_quoted_string = '\x3cdiv data-name\x3d\x22region-name\x22 class\x3d\x22main-id\x22\x3eUK\x3c/div\x3e'
double_quoted_string = "\x3cdiv data-name\x3d\x22region-name\x22 class\x3d\x22main-id\x22\x3eUK\x3c/div\x3e"


puts 'unescape single_quoted_string ' + CGI.unescapeHTML(single_quoted_string)
puts 'unescape double_quoted_string ' + CGI.unescapeHTML(double_quoted_string)

前面代码的输出是:

unescape single_quoted_string \x3cdiv data-name\x3d\x22region-name\x22 class\x3d\x22main-id\x22\x3eUK\x3c/div\x3e
unescape double_quoted_string <div data-name="region-name" class="main-id">UK</div>

我的问题是,我怎样才能让 single_quoted_string 表现得好像它的内容被双引号引起来使函数理解编码的标签?

谢谢

您的问题与HTML无关,\x3c表示ascii table中的十六进制数'3c'。 Double-quoted 字符串查找此模式并将它们转换为所需的值,single-quoted 字符串将其视为最终结果。

您可以自己检查一下 CGI 没有做任何事情。

CGI.unescapeHTML(double_quoted_string) == double_quoted_string

我知道解决问题的最简单方法是 gsub

def convert(str)
  str.gsub(/\x(\w\w)/) do
    [Regexp.last_match(1)].pack("H*")
  end
end

single_quoted_string = '\x3cdiv data-name\x3d\x22region-name\x22 class\x3d\x22main-id\x22\x3eUK\x3c/div\x3e'

puts convert(single_quoted_string)

convert所做的是获取每对十六进制转义值并将它们打包为字符。

Ruby 的解析器允许 string literals.

中的某些转义序列

double-quoted 字符串文字 "\x3c" 被识别为包含表示单个字符 < 的十六进制模式 \xnn。 (ASCII 中的 0x3C)

single-quoted 字符串字面值 '\x3c' 被按字面处理,即它代表四个字符:\x3c.

how can I make the single_quoted_string act as if its content is double-quoted

你不能。为了将这四个字符变成 < 你必须自己 解析 字符串:

str = '\x3c'

str[2, 2]         #=> "3c"  take hex part
str[2, 2].hex     #=> 60    convert to number
str[2, 2].hex.chr #=> "<"   convert to character

您可以将此应用于 gsub

str = '\x3cdiv data-name\x3d\x22region-name\x22 class\x3d\x22main-id\x22\x3eUK\x3c/div\x3e'

str.gsub(/\x\h{2}/) { |m| m[2, 2].hex.chr }
#=> "<div data-name=\"region-name\" class=\"main-id\">UK</div>"

/\x\h{2}/ 匹配文字反斜杠 (\) 后跟 x 和两个 ({2}) 十六进制字符 (\h).


仅供参考,CGI 编码的字符串如下所示:

str = "<div data-name=\"region-name\" class=\"main-id\">UK</div>"

CGI.escapeHTML(str)
#=> "&lt;div data-name=&quot;region-name&quot; class=&quot;main-id&quot;&gt;UK&lt;/div&gt;"

它使用 &...; 样式 character references