如何在Ruby中正确解码使用quoted-printable编码的字符串

4

我正在尝试解码一些出现在Mbox电子邮件存档中的Quoted-Printable编码文本。以下是我遇到困难的一个例子。

在MBox中,出现了以下文本:

"Demarcation by Theresa Castel=E3o-Lawless"

正确解码后,我认为应该显示为:

"Demarcation by Theresa Castelão-Lawless"

我说它应该正确显示的依据是:

1)电子邮件的Web存档中文本的正确呈现为"Demarcation by Theresa Castelão-Lawless"

2)此页面将“= E3”显示为Quoted-Printable对应的“ã”https://www.ic.unicamp.br/~stolfi/EXPORT/www/ISO-8859-1-Encoding.html

我尝试了下面的代码,但它给出了错误的输出。


string = "Demarcation by Theresa Castel=E3o-Lawless"

decoded_string = Mail::Encodings::QuotedPrintable.decode(string)

puts decoded_string + "\n"

上面代码的结果是“Demarcation by Theresa Castel?o-Lawless”,但就像之前所述,我想要“Demarcation by Theresa Castelão-Lawless”。

关于 2) 那个页面全部是 ISO-8859-1,又称为 ISO Latin 1。在 Ruby 中,默认情况下字符串是 UTF-8 编码。 - Stefan
1个回答

3
尽量避免使用奇怪的Rails东西,当您有纯粹的好Ruby来完成任务时。 String#unpack是您的朋友。
"Demarcation by Theresa Castel=E3o-Lawless".
  unpack("M").first. # unpack as quoted printable
  force_encoding(Encoding::ISO_8859_1).
  encode(Encoding::UTF_8)
#⇒ "Demarcation by Theresa Castelão-Lawless"

或者,正如@Stefan在评论中建议的那样,可以将源编码作为第二个参数传递:

"Demarcation by Theresa Castel=E3o-Lawless".
  unpack("M").first. # unpack as quoted printable
  encode('utf-8', 'iso-8859-1')

注意: force_encoding 在将源字符集为单字节的带有欧洲重音符号的 ISO 编码转换成目标字符集为 UTF-8 时是必需的。


你可以将源编码作为第二个参数传递:encode('utf-8', 'iso-8859-1') - Stefan
@Stefan 是的,我决定这样做会更加明确。也许我错了,我会更新答案。 - Aleksei Matiushkin
1
@AlekseiMatiushkin 我不确定如何在SO上处理这个问题,但是有另一个非常相似的问题:https://dev59.com/IE_Ta4cB1Zd3GeqPDb_0#67418207 严格来说,它不是重复的,因为这个问题有一个只包含十六进制序列而没有QP分隔符、字符集和代码的字符串。在这种情况下,unpack仍然是一个很好的解决方案,我写了完整的示例代码。对其他读者有用的话,可以参考一下其他Q/A。 - Richard Michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接