¿Cómo traduzco caracteres de 8 bits en caracteres de 7 bits? (es decir, & # 220; a U)

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

  •  02-07-2019
  •  | 
  •  

Pregunta

Estoy buscando pseudocódigo, o código de muestra, para convertir caracteres ascii de bits más altos (como & # 220; que se extiende ascii 154) en U (que es ascii 85).

Mi conjetura inicial es que, dado que solo hay unos 25 caracteres ascii que son similares a los caracteres ascii de 7 bits, habría que usar una matriz de traducción.

Avísame si puedes pensar en otra cosa.

¿Fue útil?

Solución

De hecho, tal como lo propone inexistente: " iconv " La función existe para manejar todas las conversiones extrañas, está disponible en casi todos los lenguajes de programación y tiene una opción especial que intenta convertir los caracteres que faltan en el conjunto de objetivos con aproximaciones.

Use iconv para simplemente convertir su cadena de entrada UTF-8 a ASCII de 7 bits.

De lo contrario, siempre terminarás presionando mayúsculas y minúsculas: una entrada de 8 bits usando una página de códigos diferente con un conjunto diferente de caracteres (por lo tanto, no funciona en absoluto con tu tabla de conversión), olvidé mapear un último carácter estúpido acentuado (mapeaste todo acento grave / agudo, pero olvidé mapear el caron checo o el '°' nórdico), etc.

Por supuesto, si desea aplicar la solución a un pequeño problema específico (hacer que los nombres de archivo compatibles con el sistema de archivos para su colección de música) las matrices de búsqueda sean el camino a seguir (una matriz que para cada número de código anterior 128 asigna una aproximación por debajo de 128 según lo propuesto por JeeBee, o los pares fuente / destino propuestos por vIceBerg dependiendo de las funciones de sustitución que ya están disponibles en el idioma de su elección), porque se hackea rápidamente y comprueba rápidamente si faltan elementos.

Otros consejos

Para usuarios de .NET, el El artículo en CodeProject (gracias a consejo de GvS ) responde la pregunta más correctamente que cualquier otra que haya visto hasta ahora.

Sin embargo, el código en ese artículo (en la solución # 1) es engorroso. Aquí hay una versión 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 ampliar un poco la respuesta, este método utiliza String.Normalize que:

  

Devuelve una nueva cadena cuyo valor textual es el mismo que esta cadena,   pero cuya representación binaria está en el Unicode especificado   formulario de normalización.

Específicamente en este caso utilizamos el NormalizationForm FormKD , descrito en esos mismos documentos de MSDN como tales:

  

FormKD: indica que una cadena Unicode está normalizada mediante la descomposición de compatibilidad total.

Para obtener más información sobre los formularios de normalización de Unicode, consulte Anexo # 15 de Unicode .

La mayoría de los idiomas tienen una forma estándar de reemplazar caracteres acentuados con ASCII estándar, pero depende del idioma, y ??a menudo implica reemplazar un solo carácter acentuado con dos caracteres ASCII. p.ej. en alemán & # 252; se convierte en ue. Entonces, si desea manejar correctamente los lenguajes naturales, es mucho más complicado de lo que cree.

¿Convertir Ü a U es realmente lo que te gustaría hacer? No sé sobre otros idiomas, pero en alemán Ü se convertiría en Ue, ö se convertiría en oe, etc.

Creo que simplemente no puedes.

Normalmente hago algo así:

AccentString = '& # 192; & # 194; & # 196; & # 201; & # 200; & # 202; [y todos los demás]'
ConvertString = 'AAAEEE [y todos los demás]'

Buscando el carácter en AccentString y reemplazándolo por el mismo índice en ConvertString

HTH

En la página de códigos 1251, los caracteres se codifican con 2 bytes: uno para el carácter básico y otro para la variación. Luego, cuando vuelve a codificar en ASCII, solo se conservan los caracteres básicos.

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

Parece que lo has clavado, creo. Una matriz de bytes de 128 bytes de longitud, indexada por char & amp; 127, que contiene el carácter de 7 bits correspondiente al carácter de 8 bits.

Hm, ¿por qué no simplemente cambiar la codificación de la cadena con iconv?

Realmente depende de la naturaleza de sus cadenas de origen. Si conoce la codificación de la cadena y sabe que es una codificación de 8 bits & # 8212; por ejemplo, ISO Latin 1 o similar & # 8212; entonces una simple matriz estática es suficiente:

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

Por otro lado, si tiene una codificación diferente, o si está utilizando cadenas codificadas UTF-8, probablemente encontrará las funciones en el ICU biblioteca muy útil.

Hay un artículo sobre CodeProject que se ve bien.

También la conversión usando la página de códigos 1251 me interesa (ver otra respuesta).

No me gustan las tablas de conversión, ya que el número de caracteres en Unicode es tan grande que fácilmente se pierde uno.

Creo que ya lo has clavado en la cabeza. Dado su dominio limitado, una matriz de conversión o hash es su mejor opción. No tiene sentido crear algo complejo para intentar hacerlo de forma automática.

Una matriz de búsqueda es probablemente la forma más simple y rápida de lograr esto. Esta es una forma de convertir, por ejemplo, ASCII a EBCDIC.

Los 128 caracteres superiores no tienen significados estándar. Pueden tomar diferentes interpretaciones (páginas de códigos) según el idioma del usuario.

Por ejemplo, vea portugués versus francés canadiense

A menos que conozca la página de códigos, su " traducción " se equivocará a veces.

Si va a asumir una determinada página de códigos (por ejemplo, la página de códigos original de IBM), una matriz de traducción funcionará, pero para los verdaderos usuarios internacionales, estará muy mal.

Esta es una de las razones por las que se prefiere unicode sobre el sistema anterior de páginas de códigos.

Estrictamente hablando, ASCII tiene solo 7 bits.

Pruebe el programa uni2ascii .

Utilizo esta función para arreglar una variable con acentos para pasar a una función de jabón desde 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

Y dentro de la función de jabón hago esto (para la variable Nombre de archivo):

FileName = HttpContext.Current.Server.HtmlDecode(FileName)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top