Como faço para traduzir caracteres de 8 bits em caracteres de 7 bits? (Isto é, U para L)

StackOverflow https://stackoverflow.com/questions/140422

  •  02-07-2019
  •  | 
  •  

Pergunta

Eu estou procurando pseudocódigo ou código de exemplo, para converter caracteres ASCII pouco mais altas (como, Ü que é ASCII estendido 154) em U (que é ascii 85).

Meu palpite inicial é que uma vez que existem apenas cerca de 25 caracteres ASCII que são semelhantes aos personagens 7bit ASCII, uma matriz de tradução teria que ser usado.

Deixe-me saber se você pode pensar em outra coisa.

Foi útil?

Solução

De fato, como proposto por Unexist: função "iconv" existe para lidar com todas conversão estranho para você, está disponível em quase todas as linguagens de programação e tem uma opção especial que tenta caracteres converter ausentes no conjunto de destino com aproximações.

Use iconv que simplesmente converter sua entrada string UTF-8 para ASCII 7 bits.

Caso contrário, você sempre vai acabar acertando caso canto: uma entrada de 8 bits usando uma página de código diferente, com um conjunto diferente de caracteres (assim, não funciona em todos com a sua tabela de conversão), esqueceu-se de mapear um último caracter acentuado estúpido (você mapeou tudo sotaque / aguda sepultura, mas esqueceu-se de mapear Caron Checa ou o nórdico '°'), etc.

É claro que se você deseja aplicar a solução para um pequeno problema específico (fazendo nomes amigáveis ??do sistema de arquivos para a sua coleção de música) as matrizes olhar-up são o caminho a percorrer (ou um array que para cada número de código acima 128 mapeia uma aproximação sob 128 como proposto por JeeBee, ou os / pares de origem destino proposto por vIceBerg consoante as funções de substituição já estão disponíveis no idioma de sua escolha), porque ele é rapidamente cortado em conjunto e rapidamente verificar se há elementos em falta.

Outras dicas

Para usuários .NET artigo no CodeProject (graças a da GVS ponta ), de fato, responder à pergunta mais corretamente do que qualquer outro já I visto até agora.

No entanto, o código nesse artigo (em solução # 1) é complicado. Aqui está uma versão compacta:

// Based on http://www.codeproject.com/Articles/13503/Stripping-Accents-from-Latin-Characters-A-Foray-in
private static string LatinToAscii(string inString)
{
    var newStringBuilder = new StringBuilder();
    newStringBuilder.Append(inString.Normalize(NormalizationForm.FormKD)
                                    .Where(x => x < 128)
                                    .ToArray());
    return newStringBuilder.ToString();
}

Para expandir um pouco sobre a resposta, este método utiliza String.Normalize que:

Retorna uma nova string cujo valor textual é o mesmo que esta cadeia, mas cuja representação binária está no Unicode especificado normalização formulário.

Especificamente, neste caso, usamos a NormalizationForm FormKD, descrito nesses mesmos documentos MSDN tais como:

FormKD -. Indica que uma seqüência de caracteres Unicode é normalizada utilizando a decomposição total compatibilidade

Para mais informações sobre formas de normalização unicode, consulte Unicode anexo nº 15 .

A maioria das línguas têm uma forma padrão para substituir caracteres acentuados com ASCII padrão, mas isso depende da linguagem, e que muitas vezes envolve a substituição de um único caractere acentuado com dois queridos ASCII. por exemplo. em ü alemão torna-se ue. Então, se você deseja manipular linguagens naturais corretamente é muito mais complicado do que você pensa que é.

está convertendo U para U realmente o que você gostaria de fazer? Eu não sei sobre outras línguas, mas em alemão U tornaria Ue, ö se tornaria OE, etc.

Eu acho que você simplesmente não pode.

Eu costumo fazer algo assim:

AccentString = 'ÀÂÄÉÈÊ [e todos os outros]'
ConvertString = 'AAAEEE [e todos os outros]'

Olhando para o caractere em AccentString e substituí-lo pelo mesmo índice em ConvertString

HTH

Na página de código 1251, caracteres são codificados com 2 bytes: um para o caractere de base e uma para a variação. Então, quando você codificar de volta em ASCII, apenas caracteres básicos são mantidos.

public string RemoveDiacritics(string text)
{

  return System.Text.Encoding.ASCII.GetString(System.Text.Encoding.GetEncoding(1251).GetBytes(text));

}

De: http://www.clt-services.com/blog/post/Enlever-les-accents-dans-une-chaine- (proprement) .aspx

Você parece ter pregado eu acho. A 128 bytes de comprimento de matriz de bytes, indexado pelo carvão e 127, contendo o carácter de 7 bits para o correspondente bit caracter de 8 bits.

Hm, porque não basta alterar a codificação da string com iconv?

É realmente depende da natureza de suas cordas de origem. Se você sabe a codificação do corda, e você sabe que é uma codificação de 8 bits - por exemplo, ISO Latin 1 ou similar - em seguida, uma matriz estático simples é suficiente:

static const char xlate[256] = { ..., ['é'] = 'e', ..., ['Ü'] = 'U', ... }
...
new_c = xlate[old_c];

Por outro lado, se você tem uma codificação diferente, ou se você estiver usando UTF-8 cordas codificados, provavelmente você vai encontrar as funções na biblioteca ICU muito útil.

Há um artigo sobre CodeProject que parece ser bom.

Além disso, a conversão usando página de códigos 1251 tomar o meu interesse (ver outra resposta).

Eu não como as tabelas de conversão, uma vez que o número de caracteres em Unicode são de que grande você facilmente perder um.

Eu acho que você já acertou em cheio na cabeça. Dado o seu domínio limitado, uma matriz de conversão ou hash é sua melhor aposta. Não faz sentido criar algo complexo para tentar fazê-lo automagicamente.

Uma pesquisa matriz é provavelmente a maneira mais simples e rápida de fazer isso. Esta é uma maneira que você pode converter digamos, ASCII para EBCDIC.

Os 128 caracteres superiores não têm significados padrão. Eles podem ter interpretações diferentes (páginas de código), dependendo do idioma do usuário.

Por exemplo, veja Português versus Francês Canadian

Se você não sabe a página de código, a sua "tradução" vai estar errado às vezes.

Se você estiver indo para assumir uma página de código certo (por exemplo, a página original código IBM), em seguida, uma matriz de tradução vai funcionar, mas para os verdadeiros usuários internacionais, será errado muito.

Esta é uma razão pela qual unicode é favorecido sobre o sistema mais antigo de páginas de código.

A rigor, ASCII é de apenas 7 bits.

Tente o href="http://billposer.org/Software/uni2ascii.html" rel="nofollow noreferrer"> programa .

Eu uso essa função para corrigir uma variável com acentos para passar para uma função de sabão a partir VB6:

Function FixAccents(ByVal Valor As String) As String

    Dim x As Long
    Valor = Replace(Valor, Chr$(38), "&#" & 38 & ";")

    For x = 127 To 255
        Valor = Replace(Valor, Chr$(x), "&#" & x & ";")
    Next

    FixAccents = Valor

End Function

E dentro da função sabão eu faço isso (para a variável Matrícula):

FileName = HttpContext.Current.Server.HtmlDecode(FileName)
scroll top