4 votes

Existe-t-il un moyen de décoder les chaînes codées en q en Ruby ?

Je travaille avec des mails, et les noms et les sujets sont parfois codés en q, comme ceci :

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

Y a-t-il un moyen de les décoder en Ruby ? Il semble que TMail devrait s'en charger, mais il ne le fait pas.

8voto

ankimal Points 452

Je l'utilise pour analyser les sujets des emails :

Vous pouvez essayer ce qui suit :

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

3voto

jtbandes Points 39804

Ruby comprend une méthode de décodage des chaînes de caractères Quoted-Printable :

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

Mais cela ne semble pas fonctionner sur l'ensemble de votre chaîne de caractères (y compris l'élément =?UTF-8?Q? partie au début. Peut-être que tu peux t'en sortir à partir de là, cependant.

2voto

Peter Kovacs Points 1649

C'est une question assez ancienne mais TMail::Unquoter (ou sa nouvelle incarnation Mail::Encodings) fait aussi bien le travail.

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

ou

Mail::Encodings.unquote_and_convert_to( str, 'utf-8' )

1voto

Alberto T. Points 409

La solution la plus efficace et la plus récente semble être l'utilisation de l'outil de gestion de l'information. value_decode de la méthode 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

0voto

Dorian Points 2384

Décodage ligne par ligne :

line.unpack("M")

Convertit une entrée STDIN ou fournie par un fichier de chaînes encodées en une sortie décodée :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X