2010-03-04 1 views
2

Je vais avoir un vrai problème pour obtenir des accents droit, et je crois que cela peut se produire à la plupart des langues latines, dans mon cas, portugaisRuby chaîne erreur d'accent: Plus de rencontrer les yeux

J'ai une chaîne viens comme paramètre et je dois obtenir la première lettre et le remonter! Cela devrait être trivial en rubis, mais voici le piège:

s1 = 'alow'; s1.size #=> 4 
s2 = 'álow'; s2.size #=> 5 

s1[0,1] #=> "a" 
s2[0,1] #=> "\303" 

s1[0,1].upcase #=> 'A' 
s2[0,1].upcase #=> '\303' !!! 

s1[0,1].upcase + s1[1,100] #=> "Alow" OK 
s2[0,1].upcase + s2[1,100] #=> "álow" NOT OK 

Je voudrais le rendre générique, Toute aide?

[EDIT]
J'ai trouvé que Rails Les chaînes peuvent être jetés à multibytes comme on le voit dans la classe ../active_support/core_ext/string/multibyte.rb, juste en utilisant:

s2.mb_chars[0,1].upcase.to_s #=> "Á" 

encore, @nsdk approche est plus facile à utiliser =)

+0

ce que vous avez trouvé à propos mb_chars est votre solution. Vous pouvez également requérir Multibyte de Active Support 3 dans vos applications non-Rails (je le fais tout le temps dans les applications Sinatra et les scripts système). Vous devriez répondre à votre propre question et la marquer comme une bonne réponse, pas @ nsdk. – mislav

Répondre

-1

s1.sub /^(.)/ do |char| char.upcase end

+0

Cela fonctionne parfaitement, merci beaucoup! –

+0

Cela n'a même pas de sens. – mislav

5

le caractère á est pas représenté un seul octet dans les chaînes de caractères UTF-8, mais la séquence de deux octets C3, A1. Donc, quand vous tranchez [0,1] de la chaîne, vous obtenez seulement le premier octet de celui-ci, \C3 ou \303, que vous ne pouvez pas significativement upcase. Ruby 1.8 ne fait pas Unicode, donc vous allez vous battre contre les chaînes d'octets et avoir beaucoup de problèmes comme celui-ci en essayant d'écrire des applications au niveau international. Voir par exemple. this question pour un certain arrière-plan. Ruby 1.9 corrige finalement ceci (bien que je n'aime pas son approche).

+0

Ceci est une bonne explication du problème, mais vous ne fournissez pas de solution (sauf passer en 1.9). – mislav