如何在Ruby中解码RFC 2047编码的电子邮件标题?

4

我有以下的头部信息:

From: =?iso-8859-1?Q?Marta_Falc=E3o?= <marta.falcao@example.com.br>

我可以轻松地分离出<之前的内容,这样就留下了
"=?iso-8859-1?Q?Marta_Falc=E3o?="

我该用什么来把这个变成"Marta Falcão"?

4
标题使用 RFC 2047 中的编码方案进行编码。这可能有助于作为搜索词。 - Roland Illig
1
确实如此!不仅有一个宝石可以做到这一点,https://github.com/ConradIrwin/rfc2047-ruby/,而且在搜索2047的TMail源代码时发现了一个我可以使用而不必添加新依赖项的方法。干得好,@RolandIllig :) - James A. Rosen
3个回答

9
使用更新的Mail gem: Mail::Encodings.value_decode(str) 或者 Mail::Encodings.unquote_and_convert_to(str, to_encoding)

提醒一下,Mail::Encodings#value_decode 存在编码错误,请参考 https://github.com/mikel/mail/issues/1397。如果你遇到了这个问题,我的回答可以帮到你。 - Weihang Jian

3
感谢Roland Illig的评论,他给了我两个选项:
  1. 安装rfc2047-ruby并调用Rfc2047.decode(header)
  2. 安装TMail并调用TMail::Unquoter.unquote_and_convert_to(header, 'utf-8')或者更好的选择是TMail::Address.parse(header).friendly,后者会去掉<email address>部分

第一个对我很有效!在我的gem列表中使用gem 'rfc2047',重启后按照描述调用方法...非常好用。非常感谢! - Tim

2
使用 Ruby 实现 RFC 2047 并不难:
module Rfc2047
  TOKEN = /[\041\043-\047\052\053\055\060-\071\101-\132\134\136\137\141-\176]+/.freeze
  ENCODED_TEXT = /[\041-\076\100-\176]+/.freeze
  ENCODED_WORD = /=\?(?<charset>#{TOKEN})\?(?<encoding>[QB])\?(?<encoded_text>#{ENCODED_TEXT})\?=/i.freeze

  class << self
    def encode(input)
      "=?#{input.encoding}?B?#{[input].pack('m0')}?="
    end

    def decode(input)
      match_data = ENCODED_WORD.match(input)
      raise ArgumentError if match_data.nil?

      charset, encoding, encoded_text = match_data.captures
      decoded =
        case encoding
        when 'Q', 'q' then encoded_text.unpack1('M')
        when 'B', 'b' then encoded_text.unpack1('m')
        end
      decoded.force_encoding(charset)
    end
  end
end

Rfc2047.decode '=?iso-8859-1?Q?Marta_Falc=E3o?=' # => Marta_Falcão

更新:
目前mikel/mail存在一个编码问题,可能无法正确解码字符串。
如果这真的困扰你,你可以尝试new_rfc_2047
$ gem install new_rfc_2047
$ ruby -rrfc_2047 -e 'puts Rfc2047.decode "From: =?iso-8859-1?Q?Marta_Falc=E3o?= <marta.falcao@example.com.br>"'
From: Marta Falcão <marta.falcao@example.com.br>

由于mikel/mail的源代码对我来说有些太复杂了,所以我只是为此创建了自己的gem。

Gem源码在这里:https://github.com/tonytonyjan/rfc_2047/


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