Remplacer les accents d'un enregistrement en utf8

Salut,

Je souhaiterai remplacer les accents d’une chaine provenant d’une table
encodée en UTF8 pour formater des urls correctes.

Evidement ça ne marche pas.

Mon code :


source = “à âéè”
dest = “aaee”

option = Option.find(:all)

nomOption = option.libelle_option
nomOption = nomOption.tr(source,dest)


Les accents ne sont pas remplacés avec cette méthode.

Est ce qu’il y a un moyen différent de le faire ?
Est ce que l’encodage pose problème et si oui comment contourner le
problème ?

Merci…

Le 3 mars 08 à 01:34, Frioffol F. a écrit :

Les accents ne sont pas remplacés avec cette méthode.

Est ce qu’il y a un moyen différent de le faire ?
Est ce que l’encodage pose problème et si oui comment contourner le
problème ?

Merci…

Bonjour

J’utilise ça dans Typo :

 accents = { ['á','à','â','ä','ã','Ã','Ä','Â','À'] => 'a',
   ['é','è','ê','ë','Ë','É','È','Ê'] => 'e',
   ['í','ì','î','ï','I','Î','Ì'] => 'i',
   ['ó','ò','ô','ö','õ','Õ','Ö','Ô','Ò'] => 'o',
   ['œ'] => 'oe',
   ['ß'] => 'ss',
   ['ú','ù','û','ü','U','Û','Ù'] => 'u',
   ['ç','Ç'] => 'c'
   }
 accents.each do |ac,rep|
   ac.each do |s|
     str.gsub!(s, rep)
   end
 end

Et ça marche plutôt bien (sans compter le nombre important de
caract`eres pris en compte)

Bonne
journéeFred

J’utilise le gem “unicode” pour faire ça.

require ‘unicode’

class String
def to_slug
str = Unicode.normalize_KD(self).gsub(/[^\x00-\x7F]/n,’’)
str = str.gsub(/\W+/, ‘-’).gsub(/^-+/,’’).gsub(/-+$/,’’).downcase
end
end

++

yk

Le 03/03/08, Frioffol F.[email protected] a écrit :

Hello,

une solution de plus si tu es dans Rails (je m’en sers dans Comatose):

module DiacriticsFu
def self.escape(str)

ActiveSupport::Multibyte::Handlers::UTF8Handler.normalize(str,:d).split(//
u).reject { |e| e.length > 1 }.join
end
end

la RSpec en bas de ce message si tu es intéressé!

Thibaut Barrère / LoGeek

http://blog.logeek.fr - learning content for developers
http://evolvingworker.com - tools for a better day

============= diacritics_fu_spec.rb =========================

require File.dirname(FILE) + ‘/…/spec_helper’
require ‘diacritics_fu’

describe “DiacriticsFu.escape” do

it “should remove the accents with grace” do
DiacriticsFu::escape(“éphémère”).should eql(“ephemere”)
DiacriticsFu::escape(“éêèïîù”).should eql(“eeeiiu”)
end

it “should work” do
DiacriticsFu::escape(“räksmörgÃ¥s”).should eql(“raksmorgas”)
end

KNOWN_DIACRITICS = { “a” => “à äâ”, “e” => “éèêë”, “i” => “îï”, “o”
=> “ôö”, “u” => “üû”, “c” => “ç”,
“I” => “ÏΔ, “E” => “ÊË”, “n” => “ñ”, “O” =>
“ÔÖ”, “Y” => “Ÿ”, “y” => “ÿ”, “N” => “Ñ” }

KNOWN_DIACRITICS.each do |expected_replacement,originals|
it “should transform any of ‘#{originals}’ into
‘#{expected_replacement}’” do
originals.split(//).each do |original|
DiacriticsFu.escape(original).should eql(expected_replacement)
end
end
end

end

Bonjour Thibaut,

J’ai essayé d’implémenter votre code comme monkeypatch au plugin
PermalinkFu, mais cela n’a pas fonctionné. L’avez-vous déjà fait? En
avez-vous parlé à Rick O. l’auteur du plugin?

Je ne comprends pas comment est structuré le plugin PermalinkFu car il
n’y a aucun commentaires.

Ha ben en fait je viens d’y arriver. J’avais oublié qu’il fallait
redémarrer le serveur Mongrel pour recharger le plugin. Par contre
c’est dommage par défaut, votre patch transform les espaces en %20.

Hello,

voici un patch possible :

http://pastie.caboo.se/161676

En pratique je l’injecte dans PermalinkFu (il ne fait que supprimer
les accents).

J’en profite: vu que les français ont fréquemment ce souci d’accents
dans les urls, je me dis que ça pourrait être intéressant de publier
une bonne fois pour toute une gem ou un plugin rails pour gérer ça.
Qu’en pensez-vous ?

– Thibaut

On 5 mar, 09:25, Thibaut Barrère [email protected] wrote:

dans les urls, je me dis que ça pourrait être intéressant de publier
une bonne fois pour toute une gem ou un plugin rails pour gérer ça.
Qu’en pensez-vous ?

J’aime bien je remarque juste que cette méthode a 2 petits defaults:

  • elle est 4 fois plus lente qu’une methode à base de regex très
    complète et sans doute encore pire pour une version à base de regexp
    simple. Suivant l’usage qu’on en fait ca n’est pas forcement
    dramatique
  • les translitérations qu’elle supporte ne sont pas exhautive non plus
    bien que loin d’être mauvaise. Pas de Å“ de ß .

Ca marche bien sur ‘âäà ãáäåāăąǎǟǡǻȁȃȧẵặ’ ou
‘òóôõōŏȯöỏőǒȍȏơǫọɵøồốỗổȱȫȭṍṏṑṓờớỡởợǭộǿ’ et même ‘ÇĆČĈĊ’ en revanche.
Et c’est clair que c’est plus esthétique que gérer des tableau de
correspondance de caractère. Et évidemment c’est réservé exclusivement
aux langues occidendales.

Reste à espérer que la solution miracle viendra du coté de ruby 1.9

Et �a marche plut�t bien (sans compter le nombre important de
caract`eres pris en compte)

Bonne
journ�eFred

Bonjour,

J’ai voulu implémenter la fonction de Fred ci-dessous, mais
l’interpréteur Ruby n’aime pas… les accents, justement !

def remove_accents( str )

accents = { ['á','à ','â','ä','ã','Ã','Ä','Â','À'] => 'a',
            ['é','è','ê','ë','Ë','É','È','Ê'] => 'e',
            ['í','ì','î','ï','I','Î','Ì'] => 'i',
            ['ó','ò','ô','ö','õ','Õ','Ö','Ô','Ò'] => 'o',
            ['Å“'] => 'oe',
            ['ß'] => 'ss',
            ['ú','ù','û','ü','U','Û','Ù'] => 'u'
}
accents.each do |ac,rep|
  ac.each do |s|
    str.gsub!(s, rep)
  end
end
return str

end

Est-ce un problème dû à mon environnement de développement (Eclipse) ?

Merci,

Christophe.

Salut Renaud!

J’aime bien je remarque juste que cette méthode a 2 petits defaults:

  • elle est 4 fois plus lente qu’une methode à base de regex très
    complète et sans doute encore pire pour une version à base de regexp
    simple. Suivant l’usage qu’on en fait ca n’est pas forcement
    dramatique
  • les translitérations qu’elle supporte ne sont pas exhautive non plus
    bien que loin d’être mauvaise. Pas de OE de ß .

Merci pour les retours!

En pratique je me sers de cette méthode lors de la création d’articles
dans un CMS (la perf ne pose pas de problème dans mon cas, le facteur
limitant étant le rédacteur :-).

Reste à espérer que la solution miracle viendra du coté de ruby 1.9

J’aimerais autant - car malgré tout ça fait un peu bricolage!

– Thibaut

On Thu, Mar 6, 2008 at 2:35 PM, Chris Gers32
[email protected] wrote:

J’ai voulu implémenter la fonction de Fred ci-dessous, mais
[‘ß’] => ‘ss’,
end

Est-ce un problème dû à mon environnement de développement (Eclipse) ?

Ton fichier est-il bien encodé en UTF-8 justement ?


Cyril M.
http://blog.shingara.fr

Aha ! Eh non, il ne l’était pas, justement… C’est maintenant chose
faite.

Merci,

Christophe.

J’ai voulu implémenter la fonction de Fred ci-dessous, mais
[‘ú’,‘ù’,‘û’,‘ü’,‘U’,‘Û’,‘Ù’] => ‘u’
}
accents.each do |ac,rep|
ac.each do |s|
str.gsub!(s, rep)
end
end
return str

end

IMHO l’implémentation de cette méthode n’est pas optimale, au niveau
performance elle est a peu près équivalente à la méthode de Thibault
avec un support de caractère bien moindre.

  • La table de correspondance est redéfinie à chaque execution, donc +
    de GC et du temps perdu.
  • Et il y a beaucoup trop d’itération, précompiler un nombre limité de
    regexp serait beaucoup plus performant et éviterait que gsub le fasse
    à chaque execution.

Si c’est executé une fois de temps en temps ca n’a pas d’importance
mais en cas d’utilisation intensive ca n’est pas terrible.

Cela fait bientôt un an… J’ai été occupé à faire de la gestion de
projets, mais me re-voici avec le même problème :

Cette fois, j’ai fait la substitution dans irb et elle fonctionne :

C:\Users\Christophe>irb
irb(main):001:0> str = “éthanol”
=> “\202thanol”
irb(main):002:0> str.gsub(‘é’, ‘e’)
=> “ethanol”

Quelqu’un peut-il m’expliquer pourquoi ça ne fonctionne pas dans la
méthode de Fred ci-dessous ? Comme je l’ai indiqué plus haut, mon
fichier source est bien encodé en UTF-8.

def ApplicationHelper.remove_accents( str )

accents = { ['á','à ','â','ä','ã','Ã','Ä','Â','À'] => 'a',
            ['é','è','ê','ë','Ë','É','È','Ê'] => 'e',
            ['í','ì','î','ï','I','Î','Ì'] => 'i',
            ['ó','ò','ô','ö','õ','Õ','Ö','Ô','Ò'] => 'o',
            ['Å“'] => 'oe',
            ['ß'] => 'ss',
            ['ú','ù','û','ü','U','Û','Ù'] => 'u'
}
accents.each do |ac,rep|
  ac.each do |s|
    str.gsub!(s, rep)
  end
end
return str

end

J’ai également essayé la méthode escape( str ) de Thibaud (au-dessus),
mais l’exécution de l’application semble s’interrompre (je n’ai sûrement
pas su m’en servir…).

Merci,

Christophe.

Oui, je réalise que cette fonction n’est pas optimale, mais étant peu
expérimenté en Ruby, c’était la solution la plus claire.

Mais de toute façon, elle ne marche pas dans mon cas : lorsque je fais
tourner l’application dans le débogueur, je vois que Ruby ne reconnaît
pas les caractères accentués reçus via une URL et les affiche comme des
données binaires… Pourtant, ils semblent bien encodés dans l’URL ; la
console affiche ceci :

Parameters: {… “description”=>“ÂÄéèÊËçîïÏÔü”, “controller”=>…}

http://localhost/wrk_vpreparations/by_multi_criteria_xml?description=������������

SELECT DESC_FR FROM wrk_vpreparations WHERE (upper( desc_fr ) like
‘%ÂÄéèÊËçîïÏÔü%’)

Donc on voit bien que toutes les lettres accentuées sont bien passées
via l’URL, mais dans le SELECT, elles devraient avoir été converties en
AAEEEECIIIOU (j’applique d’abord la fonction remove_accents(), puis
upcase).

C’est bien au niveau de Ruby que ça déconne, parce que si j’essaie de
faire un simple “é”.upcase dans script/console (irb de RadRails), ça
plante… En revanche, la même chose dans irb en ligne de commande
renvoie “\202” ; je n’y comprends plus rien !

J’ai défini une version “light” de la méthode dans irb ; elle fonctionne
:

irb(main):017:0> def remove_accents( str )
irb(main):018:1> accents = { [‘é’] => ‘e’}
irb(main):019:1> accents.each do |ac, rep|
irb(main):020:2* ac.each do |s|
irb(main):021:3* str.gsub!(s, rep)
irb(main):022:3> end
irb(main):023:2> end
irb(main):024:1> return str
irb(main):025:1> end
=> nil
irb(main):026:0> remove_accents( “éthanol” )
=> “ethanol”

Pourrait-il y avoir un paramétrage de l’encodage dans un fichier de
configuration quelque part ou au niveau d’Eclipse ?

Christophe.

Fernando P. wrote:

irb(main):026:0> remove_accents( “éthanol” )
=> “ethanol”

Pourrait-il y avoir un paramétrage de l’encodage dans un fichier de
configuration quelque part ou au niveau d’Eclipse ?

Christophe.

“à âéè”.parameterize.to_s :slight_smile:

Malheureusement, lorsque j’utilise la méthode parameterize, j’ai le
message d’erreur suivant :

NoMethodError (undefined method normalize' for "�thanol":String): c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/inflector.rb:283:intransliterate’
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/inflector.rb:262:in
parameterize' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/core_ext/string/inflections.rb:106:inparameterize’

Alors que j’ai passé le paramètre “éthanol” qui s’est transformé en
“%E9” dans l’URL provenant d’une application Flex tournant dans un
plugin Flash. Et lorsque je passe simplement “ethanol”, je n’ai pas
l’erreur. On dirait bien que la transcodification du “%E9” en “é” a
déconné, mais je ne sais pas à quel niveau.

irb(main):026:0> remove_accents( “éthanol” )
=> “ethanol”

Pourrait-il y avoir un paramétrage de l’encodage dans un fichier de
configuration quelque part ou au niveau d’Eclipse ?

Christophe.

“à âéè”.parameterize.to_s :slight_smile:

Hello,

tu utilises activesupport 2.2.2, je crois que parameterize n’existait
pas encore dans cette release.

Je crois que tu as gagné le droit de te rabattre sur diacritics_fu
(github.com/thbar/diacritics_fu/tree).

– Thibaut

Voici un exemple dans irb. Lorsque l’encodage n’est pas spécifié, la
fonction “normalize” n’est pas trouvée pour la chaîne de caractères “a b
c”. Puis, lorsque je spécifie l’encodage (UTF8), ça fonctionne avec “a b
c”, mais pas avec "é è ç à ". Or, les seuls encodages disponibles sont
“NONE”, “UTF8” et deux encodages japonais “EUC” et “SJIS”…

irb(main):002:0> require ‘active_support’
=> true
irb(main):003:0> “a b c”.parameterize
NoMethodError: undefined method normalize' for "a b c":String from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/inflector.rb:292:intransliterate’
from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/inflector.rb:261:in
parameterize' from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/core_ext/string/inflections.rb:106:inparameterize’
from (irb):3
irb(main):004:0> $KCODE = ‘u’
=> “u”
irb(main):005:0> “a b c”.parameterize
=> #<ActiveSupport::Multibyte::Chars:0x40fc07c @wrapped_string=“a-b-c”>
irb(main):006:0> "é è ç à ".parameterize
NoMethodError: undefined method normalize' for "\202 \212 \207 \205":String from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/inflector.rb:292:intransliterate’
from
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/inflector.rb:261:in
parameterize' from c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/core_ext/string/inflections.rb:106:inparameterize’
from (irb):6