我正在处理邮件,有时名称和主题使用q编码,例如:
=?UTF-8?Q?J=2E_Pablo_Fern=C3=A1ndez?=
有没有办法在Ruby中对它们进行解码?看来TMail应该照顾好它,但它没有这样做。
我用它来解析电子邮件主题:
您可以尝试以下操作:
str = "=?UTF-8?Q?J=2E_Pablo_Fern=C3=A1ndez?="
if m = /=\?([A-Za-z0-9\-]+)\?(B|Q)\?([!->@-~]+)\?=/i.match(str)
case m[2]
when "B" # Base64 encoded
decoded = Base64.decode64(m[3])
when "Q" # Q encoded
decoded = m[3].unpack("M").first.gsub('_',' ')
else
p "Could not find keyword!!!"
end
Iconv.conv('utf-8',m[1],decoded) # to convert to utf-8
end
Ruby包括一种对带引号的可打印字符串进行解码的方法:
puts "Pablo_Fern=C3=A1ndez".unpack "M"
# => Pablo_Fernández
但是这似乎不适用于您的整个字符串(包括开头的=?UTF-8?Q?
部分。不过,也许您可以从那里开始解决。
这是一个很老的问题,但是TMail :: Unquoter(或它的新化身Mail :: Encodings)也可以完成这项工作。
TMail::Unquoter.unquote_and_convert_to(str, 'utf-8' )
或
Mail::Encodings.unquote_and_convert_to( str, 'utf-8' )
每行解码:
line.unpack("M")
将STDIN或文件提供的编码字符串输入转换为解码输出:
if ARGV[0]
lines = File.read(ARGV[0]).lines
else
lines = STDIN.each_line.to_a
end
puts lines.map { |c| c.unpack("M") }.join
这可以帮助想要测试电子邮件的任何人。 delivery.html_part通常经过编码,但是可以使用.decoded
解码为纯HTML主体。
test "email test" do
UserMailer.confirm_email(user).deliver_now
assert_equal 1, ActionMailer::Base.deliveries.size
delivery = ActionMailer::Base.deliveries.last
assert_equal "Please confirm your email", delivery.subject
assert delivery.html_part.decoded =~ /Click the link below to confirm your email/ # DECODING HERE
end
似乎是使用value_decode
的Mail gem方法的最有效,最新的解决方案。
> Mail::Encodings.value_decode("=?UTF-8?Q?Greg_of_Google?=")
=> "Greg of Google"
https://www.rubydoc.info/github/mikel/mail/Mail/Encodings#value_decode-class_method