Is there a way to decode q-encoded strings in Ruby?

前端 未结 6 611
星月不相逢
星月不相逢 2021-01-13 16:05

I\'m working with mails, and names and subjects sometimes come q-encoded, like this:

=?UTF-8?Q?J=2E_Pablo_Fern=C3=A1ndez?=

Is there a way t

相关标签:
6条回答
  • 2021-01-13 16:29

    This is a pretty old question but TMail::Unquoter (or its new incarnation Mail::Encodings) does the job as well.

    TMail::Unquoter.unquote_and_convert_to(str, 'utf-8' )
    

    or

    Mail::Encodings.unquote_and_convert_to( str, 'utf-8' )
    
    0 讨论(0)
  • 2021-01-13 16:29

    The most efficient and up to date solution it seems to use the value_decode method of the 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

    0 讨论(0)
  • 2021-01-13 16:37

    I use this to parse email subjects:

    You could try the following:

    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
    
    0 讨论(0)
  • 2021-01-13 16:37

    This might help anyone wanting to test an email. delivery.html_part is normally encoded, but can be decoded to a straight HTML body using .decoded.

    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
    
    0 讨论(0)
  • 2021-01-13 16:44

    Decoding on a line-per-line basis:

    line.unpack("M")
    

    Convert STDIN or file provided input of encoded strings into a decoded output:

    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
    
    0 讨论(0)
  • 2021-01-13 16:53

    Ruby includes a method of decoding Quoted-Printable strings:

    puts "Pablo_Fern=C3=A1ndez".unpack "M"
    # => Pablo_Fernández
    

    But this doesn't seem to work on your entire string (including the =?UTF-8?Q? part at the beginning. Maybe you can work it out from there, though.

    0 讨论(0)
提交回复
热议问题