有没有办法在Ruby中解码q编码的字符串?

我正在处理邮件,名称和主题有时会进行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包含一种解码Quoted-Printable字符串的方法:

 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