Ruby 1.9, force_encoding, mas verifique
Eu tenho uma string que li de algum tipo de entrada.
Para o melhor do meu conhecimento, é UTF8. OK:
<code>string.force_encoding("utf8") </code>
Mas se essa string tiver bytes nela que não sejam de fato UTF8 legais, quero saber agora e agir.
Ordinariamente, o force_encoding ("utf8") será criado se encontrar tais bytes? Euacreditam não vai.
Se eu estivesse fazendo uma#codificar Eu poderia escolher entre as opções úteis com o que fazer com caracteres inválidos na codificação de origem (ou codificação de destino).
Mas eu não estou fazendo um #encode, estou fazendo um #force_encoding. Não tem essas opções.
Faz sentido
<code>string.force_encoding("utf8").encode("utf8") </code>
obter uma exceção imediatamente? Normalmente codificaçãode utf8para utf8 não faz qualquer sentido. Mas talvez esta seja a maneira de aumentar imediatamente se houver bytes inválidos? Ou use o:replace
opção etc para fazer algo diferente com bytes inválidos?
Mas não, parece que isso não funciona.
Ninguem sabe?
<code>1.9.3-p0 :032 > a = "bad: \xc3\x28 okay".force_encoding("utf-8") => "bad: \xC3( okay" 1.9.3-p0 :033 > a.valid_encoding? => false </code>
Ok, mas como eu encontro e elimino esses bytes ruins? Estranhamente, isso não aumenta:
<code>1.9.3-p0 :035 > a.encode("utf-8") => "bad: \xC3( okay" </code>
Se eu estivesse convertendo para uma codificação diferente, seria!
<code>1.9.3-p0 :039 > a.encode("ISO-8859-1") Encoding::InvalidByteSequenceError: "\xC3" followed by "(" on UTF-8 </code>
Ou, se eu contasse, substituiria por um "?" =>
<code>1.9.3-p0 :040 > a.encode("ISO-8859-1", :invalid => :replace) => "bad: ?( okay" </code>
Então, o ruby tem inteligência para saber o que são bytes ruins no utf-8 e substituí-los por algo mais - ao converter para uma codificação diferente. Mas eu nãoquer para converter para uma codificação diferente, eu quero ficar utf8 - mas eu poderia querer aumentar se houver um byte inválido lá, ou eu poderia querer substituir bytes inválidos com caracteres de substituição.
Não há alguma maneira de obter ruby para fazer isso?
atualizar Eu acredito que isso finalmente foi adicionado ao ruby em 2.1, com o String # scrub presente na versão 2.1 para fazer isso. Então olhe para isso!