Conversion d'un fichier UTF-8 en ASCII (au mieux)

23

J'ai un fichier en UTF-8 qui contient des textes en plusieurs langues. Beaucoup sont des noms de personnes. J'ai besoin de le convertir en ASCII et j'ai besoin que le résultat soit aussi décent que possible.

Il existe de nombreuses façons d'aborder la conversion d'un encodage plus large en un encodage plus étroit. La transformation la plus simple serait de remplacer tous les caractères non ASCII par un espace réservé, comme «_». Si je connais la langue dans laquelle le fichier est écrit, il existe des possibilités supplémentaires, comme la romanisation.

Quel outil Unix ou bibliothèque de langage de programmation disponible sur Unix peut me donner une conversion décente (au mieux) de UTF-8 en ASCII?

La plupart du texte est en langues européennes de type latin.

user7610
la source
1
savez-vous où commence la langue? Il y a par exemple une différence sur la façon de gérer la non-disponibilité d'un tréma (comme sur le ö). En allemand, vous pouvez toujours écrire "oe", mais par exemple en néerlandais l'indisponibilité d'un tréma peut être mieux "décrite" par un tiret suivi du caractère tréma (et là le "oe" serait une diphtongue complètement différente)
Anthon
Comment définissez-vous «aussi décent que possible»? La vraie difficulté est de définir les mappages. Par rapport à cela, la tâche de programmation est triviale. Les mappages réellement utilisés varient beaucoup et peuvent être spécifiques à la langue de deux manières: ils dépendent de la langue du texte et de la langue supposée du lecteur (en particulier en ce qui concerne la romanisation).
Jukka K. Korpela
@ JukkaK.Korpela "aussi décent que possible" est bien sûr défini par ceux qui ont créé "l'outil Unix ou la bibliothèque de langages de programmation disponibles sur Unix" que je demande. Si le mieux que je puisse faire est de remplacer tout ce qui n'est pas ASCII par un trait de soulignement, il n'y a pas grand-chose d'autre à faire. Sauf écrire mon propre outil, ce que je ne ferai pas. Je suppose qu'Unix @ SO n'est peut-être pas le meilleur endroit pour cette question…
user7610
1
@ user7610 Autre que iconvet tr, il existe Unidecode . Je ne le connais pas, mais il pourrait faire ce que vous voulez, si vous pouvez utiliser Python.
yellowantphil
1
@yellowantphil ou node-unidecode en JavaScript / node, UnidecodeSharp en C♯, ou Text :: Unidecode en Perl, qui se trouve être le premier de ce nom. Je suppose qu'il existe d'autres versions.
user7610

Réponses:

11
konwert utf8-ascii

Il effectuera la conversion au mieux, en fonction des tables de conversion. Si vous connaissez approximativement la langue d'entrée, il existe des filtres spécifiques à la langue qui donnent de meilleurs résultats, par exemple

konwert utf8-xmetodo

est la conversion de l'espéranto en représentation x-metodo,

konwert UTF8-tex

va essayer de faire une représentation TeX des signes diacritiques, il y a des paramètres spécifiques au langage:

konwert UTF8-ascii/de

translittérera "ä" en "ae" (coutume pour l'allemand) au lieu de "a"

konwert UTF8-ascii/rosyjski

utilisera les règles polonaises pour translittérer le russe, au lieu de celles "anglaises", etc ...

Radovan Garabík
la source
S'agit-il du dernier emplacement du konwertsite Web? Est-il emballé n'importe où? github.com/taw/konwert/tree/master/konwert-1.8
Nemo
25

Cela fonctionnera pour certaines choses:

iconv -f utf-8 -t ascii//TRANSLIT

echo ĥéĺłœ π | iconv -f utf-8 -t ascii//TRANSLITretourne helloe ?. Tous les caractères qui iconvne savent pas convertir seront remplacés par des points d'interrogation.

iconvest POSIX, mais je ne sais pas si tous les systèmes ont l' TRANSLIToption. Cela fonctionne pour moi sur Linux. En outre, l' IGNOREoption supprimera silencieusement les caractères qui ne peuvent pas être représentés dans le jeu de caractères cible (voir man iconv_open).

Une option inférieure mais compatible POSIX est à utiliser tr. Cette commande remplace tous les points de code non ASCII par un point d'interrogation. Il lit le texte UTF-8 un octet à la fois. «É» peut être remplacé par E?ou ?, selon qu'il a été codé à l'aide d'un accent de combinaison ou d'un caractère précomposé.

echo café äëïöü | tr -d '\200-\277' | tr '\300-\377' '[?*]'

Cet exemple revient caf? ?????, en utilisant des caractères précomposés.

yellowantphil
la source
trn'est pas censé fonctionner un octet à la fois. GNU tr le fait, mais c'est un bug.
Stéphane Chazelas
3
iconv -f utf-8 -t ascii//TRANSLITa bien fonctionné pour moi. Il a changé les guillemets bouclés en guillemets droits. Merci.
Colonel Panic
Notez que iconv s'étouffera avec les caractères fortement accentués tels que Pinyin.
sventechie
Notez que cela //TRANSLITfonctionne également pour d'autres jeux de caractères, par exemple iso-8859-1//TRANSLIT.
Skippy le Grand Gourou
iconvdonne iconv: illegal input sequence at position 1234et tronque le fichier pour moi. Ce serait bien s'il supprimait simplement le personnage et tentait de reprendre la séquence.
jozxyqk
2

J'ai un fichier en UTF-8 qui contient [les noms des personnes] en plusieurs langues [que je veux convertir en quelque chose de significatif en ASCII].

Vous voulez dire que vous voulez pouvoir convertir les noms suivants en une chaîne ASCII à laquelle la personne concernée ne s'opposerait pas?

  • ஸ்றீனிவாஸ ராமானுஜன் ஐயங்கார்
  • عبد الله الثاني بن الحسين

Je soupçonne qu'aucun outil automatisé ne peut le faire. Il peut y avoir soit pas ou beaucoup de latinisations de noms personnels. Le logiciel ne peut pas choisir la version culturellement acceptable. Du moins pas sans que le logiciel en sache beaucoup sur la culture de la personne impliquée.

Voir également /programming//a/1398403/477035

RedGrittyBrick
la source
2
perl -e 'use utf8; use Text::Unidecode; print unidecode("عبد الله الثاني بسين")'produit `` bd llh lthny bn lHsyn` qui est assez bonne translittération pour mes besoins.
user7610
4
@ user7610: Très bien, mais le roi Abdulla II de Jordanie pourrait ne pas être d'accord. Je préparerais une explication au cas où quelqu'un d'important se plaindrait au PDG :-)
RedGrittyBrick
2

J'ai fini par utiliser Perl avec Text :: Unidecode pour cela. Exemple:

perl -e 'use utf8; use Text::Unidecode; print unidecode("عبد الله الثاني بسين")

produit bd llh lthny bn lHsyn, ce qui est un résultat acceptable à mes fins.

user7610
la source