12
votes

Équivalent de iconv.conv ("utf-8 // ignore", ...) dans Ruby 1.9.x?

Je lis, je lis les données d'une source distante et obtenez parfois des caractères dans un autre codage. Ils ne sont pas importants.

J'aimerais obtenir une «meilleure» chaîne UTF-8 et ignorer les données non valides.

Objectif principal est d'obtenir une chaîne que je peux utiliser et non à des erreurs telles que:

  • Encodage :: UndefinedConversionError: "\ xff" de ASCII-8BIT à UTF-8:
  • séquence d'octets invalide dans UTF-8

2 commentaires

Vous avez posté une réponse et l'a supprimé. Cette réponse avait l'air utile. Pouvez-vous nous dire pourquoi ce n'est pas correct / utile?


Indiqué et commenté.


6 Réponses :


15
votes

Je pensais que c'était ce qu'il s'agissait:

string.encode ("utf-8",: invalide =>: remplacer,: UNDEF =>: Remplacer,: remplacer => "?")

remplacera toutes les connues avec '?'.

Pour ignorer toutes les inconnues, : remplacer => '' :

string.encode ("utf-8",: invalide =>: remplacer,: UNDEF =>: Remplacer: remplacer => "")

EDIT:

Je ne suis pas sûr que cela soit fiable. Je suis allé en mode paranoïde et utilisez:

string.encode ("utf-8", ...). Force_encoding ('utf-8')

Le script semble fonctionner, d'accord maintenant. Mais je suis à peu près sûr que j'avais eu des erreurs avec cela plus tôt.

edit 2:

Même avec cela, je continue à obtenir des erreurs intermittentes. Pas à chaque fois, pensez vous. Juste parfois.


3 commentaires

Avez-vous déjà compris cela? J'essaie de déterminer si iconv peut être remplacé en toute sécurité avec String # encoder dans 1.9.3 (puisqu'il vous avertit de déprécations), mais je ne peux pas dire à votre commentaire si tel est le cas. .


Remarque pour les débutants: Les ellipses de l'édition Reportez-vous au code répété - la ligne complète est la suivante: string.encode ("utf-8",: invalide =>: remplacer,: UNDEF =>: Remplacer => "") .force_coding ('utf-8')


Vous devez forcer_coding pour définir la chaîne sur le codage correct en premier. (Remarque: cela ne fait aucun codage, il vient de définir une représentation) s'il s'agit d'un document HTML, le codage de la page peut généralement être trouvé dans les balises Meta. Ensuite, utilisez l'encode avec remplacer invalide / UNDEF pour obtenir la chaîne codée UTF-8.



2
votes

Cela fonctionne bien pour moi:

"String".encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => "").force_encoding('UTF-8')


0 commentaires

3
votes

ficelle # caractères strong> ou string # chacun_char strong> peut également être utilisé.

p [
  'abcd' == str.scrub(''),
  'abcd' == str.scrub{ |c| '' }
]


3 commentaires

Si vous avez vraiment besoin d'iconv depuis Ruby 2.0, considérez gem iconv .


Merci @masakiélastique, gem iconv corrigé le problème.


Nous avons des problèmes avec le contenu collé de Word beaucoup et basé sur la réponse ci-dessus, cela a aidé beaucoup: DEF Find_Invalid_chars (s) S.Chars.select {| C | ! c.valid_encoding? } finir



0
votes

Avec un peu d'aide de @masakiélastic, j'ai résolu ce problème à des fins personnelles à l'aide de la méthode #chars.

L'astuce consiste à décomposer chaque caractère dans sa propre bloc séparé de sorte que RUBY peut échouer .

ruby ​​ a besoin pour échouer quand il affronte le code binaire, etc. Si vous n'autorisez pas Ruby pour aller de l'avant et échouer à sa route difficile en ce qui concerne cette affaire. J'utilise donc la méthode de la chaîne de # caractères pour casser la chaîne donnée dans un tableau de caractères. Ensuite, je passe ce code dans une méthode de désinfection qui permet au code d'avoir des "microfailures" (ma monnaie) dans la chaîne.

Donc, étant donné une chaîne "sale", disons que vous avez utilisé le fichier #read sur une image. (mon cas) xxx

permettant au code d'échouer quelque part dans le processus semble être le meilleur moyen de passer à travers elle. Tant que vous contenir ces échecs à l'intérieur des blocs, vous pouvez saisir ce qui est lisible par les parties UTF-8-Seul-acceptation de Ruby


0 commentaires

2
votes

Pour ignorer toutes les parties inconnues de la chaîne qui ne sont pas correctement utilisées UTF-8 codées ce qui suit (comme vous l'avez affiché à l'origine) fait presque ce que vous voulez.

string.encode('UTF-16', :invalid => :replace, :replace => '').encode('UTF-8')


0 commentaires

0
votes

Je n'ai pas eu de chance avec les utilisations d'une ligne de la chaîne # encode ala string.encode ("utf-8",: invalide =>: remplacer,: UNDEF =>: Remplacer: remplacer => "?") . Ne travaillez pas de manière fiable pour moi.

Mais j'ai écrit un "remblayage" pur de rubis de chaîne # gommage à IRI 1.9 ou 2.0 ou tout autre rubis qui n'offre pas de frotter # gommage.

https://github.com/jrochkind/scrub_rb

Il fait de la chaîne # Gommage disponible dans des rubis qui ne l'ont pas; Si elle est chargée dans l'IRM 2.1, il ne fera rien et vous utiliserez toujours la chaîne intégrée # Gommage. Il peut donc vous permettre d'écrire facilement du code qui fonctionnera sur l'une de ces plates-formes.

La mise en œuvre est quelque peu similaire à certaines des autres solutions Char-By-Char proposées dans d'autres réponses, mais elle n'utilise pas d'exceptions pour le contrôle de flux (ne le faites pas), est testée et fournit une API compatible avec IRM 2.1 String # Scrub


0 commentaires