【问题标题】:How to decode an RFC 2047 encoded email header in Ruby?如何在 Ruby 中解码 RFC 2047 编码的电子邮件标头?
【发布时间】:2011-11-21 06:41:10
【问题描述】:

我有以下标题:

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

我可以很容易地把&lt;之前的东西分开,这让我有了

"=?iso-8859-1?Q?Marta_Falc=E3o?="

我可以用什么把它变成"Marta Falcão"

【问题讨论】:

  • 标头使用 RFC 2047 中的方案进行编码。也许这有助于作为搜索词。
  • 确实如此!不仅有一个宝石,github.com/ConradIrwin/rfc2047-ruby,在 TMail 源中搜索 2047 发现了一种我可以在不添加新依赖项的情况下使用的方法。干得好,@RolandIllig :)

标签: ruby encoding tmail


【解决方案1】:

使用 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 当前有一个encoding issue,它可能无法正确解码字符串。

如果你真的很困扰,你可以试试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。

宝石来源在这里:https://github.com/tonytonyjan/rfc_2047/

【讨论】:

    【解决方案2】:

    使用较新的Mail gem:

    Mail::Encodings.value_decode(str)Mail::Encodings.unquote_and_convert_to(str, to_encoding)

    【讨论】:

    【解决方案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,后者去掉了&lt;email address&gt;部分

    【讨论】:

    • 第一个对我来说很好用! gem 'rfc2047',在我的 gem 列表中,重新启动,并按照描述调用方法.. 很有魅力。非常感谢!
    猜你喜欢
    • 2017-10-24
    • 2010-09-12
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多