On m'a demandé de définir le code de caractère par défaut de la chaîne de caractères sur Shift-jis lorsque je crache du CSV dans mon travail actuel.
Le code de caractère par défaut pour les chaînes de caractères Ruby est UTF-8, j'ai donc pensé qu'il serait possible de le réaliser en le convertissant simplement en Shift-jis lors de la décharge de CSV, mais j'étais accro à autre chose.
Certaines personnes peuvent aussi en être accro, je vais donc décrire la solution.
L'éjection CSV peut être implémentée relativement facilement en utilisant la méthode generate de la classe CSV de la bibliothèque Ruby.
Image de mise en œuvre ↓
require "csv"
text =<<-EOS
id,first name,last name,age
1,taro,tanaka,20
2,jiro,suzuki,18
3,ami,sato,19
4,yumi,adachi,21
EOS
csv = CSV.generate(text, headers: true) do |csv|
csv.add_row(["5", "saburo", "kondo", "34"])
end
Référence de code: https://docs.ruby-lang.org/ja/latest/method/CSV/s/generate.html
Si vous souhaitez convertir en shift-jis, vous pouvez spécifier l'encodage de sortie à l'aide de la touche: encoding.
CSV.generate(text, headers: true, encoding: "SJIS")
Avec cette option, l'encodage de sortie est automatiquement converti de utf-8 en shift-jis.
Lorsque je l'ai implémenté ici, l'erreur suivante s'est produite pour une raison quelconque .....
incompatible character encodings: Windows-31J and UTF-8
Recherchez pourquoi vous obtenez une erreur de codage.
Suite à la recherche de la chaîne de caractères à l'origine d'une erreur, une erreur s'est produite dans la chaîne de caractères suivante.
"AAA−0001"
C'est une chaîne qui ne semble pas étrange, pourquoi est-ce une erreur?
Après un examen plus approfondi, il semble que la conversion des caractères suivants en shif-jis entraînera une erreur d'exception.
Code de caractère (UTF-8) | lettre | Remarques |
---|---|---|
U+00A2 | ¢ | Symbole du cent (devise) |
U+00A3 | £ | Symbole de la livre (devise) |
U+00AC | ¬ | PAS symbole |
U+2016 | ‖ | Double vertical line |
U+2212 | − | Signe moins |
U+301C | 〜 | Dash de vague |
Référence: https://osa.hatenablog.com/entry/2014/08/21/113602
"AAA−0001"
Puisque cette chaîne contient - (signe moins), on suppose qu'une erreur d'exception s'est produite.
Je comprends la cause de l'erreur. Alors, comment le résolvez-vous?
Le moyen le plus simple est d'étendre la classe de chaînes en utilisant la classe ouverte de Ruby.
Ruby n'a aucune restriction sur l'héritage de classe. Même les classes de bibliothèque intégrées telles que la classe String et la classe Array peuvent être héritées pour définir leurs propres classes.
Ajoutez donc une méthode à la classe String pour éviter les exceptions lors de la conversion vers Windows-31J comme suit.
class String
def sjisable
str = self
#Remplacez les caractères de la table de conversion par les caractères ci-dessous
from_chr = "\u{301C 2212 00A2 00A3 00AC 2013 2014 2016 203E 00A0 00F8 203A}"
to_chr = "\u{FF5E FF0D FFE0 FFE1 FFE2 FF0D 2015 2225 FFE3 0020 03A6 3009}"
str.tr!(from_chr, to_chr)
#Des caractères illégaux ont fui de la table de conversion?Convertir puis revenir en UTF8 pour éviter de futures exceptions
str = str.encode("Windows-31J","UTF-8",:invalid => :replace,:undef=>:replace).encode("UTF-8","Windows-31J")
end
end
Référence du code: https://qiita.com/yugo-yamamoto/items/0c12488447cb8c2fc018
En exécutant cette méthode à l'endroit où une erreur d'exception se produit, l'erreur d'exception ne se produira pas.
"AAA−0001".sjisable
Les classes ouvertes sont très puissantes et peuvent être utilisées pour améliorer l'efficacité du développement.
D'un autre côté, c'est bien d'ajouter une méthode unique à la classe standard Ruby, mais même si vous lisez le code, vous ne pouvez pas dire qui a défini la méthode où et dans quel but, mais plutôt améliorer l'efficacité du développement de toute l'équipe. Laisse tomber.
Un autre inconvénient possible est qu'une erreur se produit à un moment inattendu.
Ou est-ce la responsabilité de la classe String de changer le code de caractère en Shift_JIS pour certaines personnes, ou est-ce la responsabilité de la classe qui gère CSV car il est nécessaire lors de la conversion en CSV? Je pense qu'il y aura une question.
Donc, si vous n'utilisez pas la classe ouverte, il est préférable de créer quelque chose comme la classe CsvUtility, de consolider les procédures de gestion du CSV et de l'implémenter afin qu'il puisse être affiché sous la forme Shift_JIS ou UTF-8. Devenir.
[Junichi Ito. Introduction à Ruby pour les professionnels Des spécifications du langage aux techniques de développement / débogage pilotées par les tests](https://www.amazon.co.jp/dp/B077Q8BXHC/ref=dp-kindle-redirect?_encoding = UTF8 & btkr = 1)