Come posso tradurre i caratteri a 8 bit in caratteri a 7 bit? (ovvero da Ü a U)

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

  •  02-07-2019
  •  | 
  •  

Domanda

Sto cercando pseudocodice, o codice di esempio, per convertire caratteri ASCII bit più alti (come, Ü che è esteso ASCII 154) in U (che è ASCII 85).

La mia ipotesi iniziale è che poiché ci sono solo circa 25 caratteri ASCII che sono simili ai caratteri ASCII a 7 bit, si dovrebbe usare un array di traduzione.

Fammi sapere se riesci a pensare ad altro.

È stato utile?

Soluzione

In effetti, come proposto da inesistere: & Quot; iconv " esiste una funzione per gestire tutte le strane conversioni per te, è disponibile in quasi tutti i linguaggi di programmazione e ha un'opzione speciale che cerca di convertire i caratteri mancanti nel set target con approssimazioni.

Usa iconv per convertire semplicemente la tua stringa UTF-8 di input in ASCII a 7 bit.

Altrimenti, finirai sempre per colpire il caso angolare: un input a 8 bit usando una tabella codici diversa con un diverso set di caratteri (quindi non funziona affatto con la tua tabella di conversione), hai dimenticato di mappare un ultimo carattere accento stupido (hai mappato tutto accento grave / acuto, ma ho dimenticato di mappare il caron ceco o il "°" nordico, ecc.

Ovviamente se si desidera applicare la soluzione a un piccolo problema specifico (rendere i nomi di file compatibili con il file system per la propria raccolta musicale), gli array di ricerca sono la strada da percorrere (sia un array che per ciascun numero di codice sopra 128 mappa un'approssimazione sotto 128 come proposto da JeeBee, o le coppie sorgente / target proposte da vIceBerg a seconda delle funzioni di sostituzione già disponibili nella tua lingua preferita), perché viene rapidamente violato insieme e controlla rapidamente la presenza di elementi mancanti.

Altri suggerimenti

Per gli utenti di .NET il l'articolo in CodeProject (grazie a Consiglio di GvS ) risponde davvero alla domanda più correttamente di qualsiasi altro visto finora.

Tuttavia il codice in quell'articolo (nella soluzione n. 1) è ingombrante. Ecco una versione compatta:

// 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();
}

Per espandere un po 'la risposta, questo metodo utilizza String.Normalize che:

  

Restituisce una nuova stringa il cui valore testuale è lo stesso di questa stringa,   ma la cui rappresentazione binaria si trova nell'Unicode specificato   modulo di normalizzazione.

Nello specifico in questo caso utilizziamo NormalizationForm FormKD , descritto in quegli stessi documenti MSDN come tali:

  

FormKD - Indica che una stringa Unicode è normalizzata usando la decomposizione a piena compatibilità.

Per ulteriori informazioni sui moduli di normalizzazione unicode, consultare Unicode Annex # 15 .

La maggior parte delle lingue ha un modo standard per sostituire i caratteri accentati con ASCII standard, ma dipende dalla lingua e spesso comporta la sostituzione di un singolo carattere accentato con due caratteri ASCII. per esempio. in tedesco & # 252; diventa ue. Quindi, se vuoi gestire correttamente le lingue naturali, è molto più complicato di quanto pensi.

Sta convertendo & # 220; davvero cosa vorresti fare? Non conosco altre lingue ma in tedesco & # 220; diventerebbe Ue, & # 246; diventerebbe oe, ecc.

Penso che proprio non puoi.

Di solito faccio qualcosa del genere:

AccentString = 'ÀÂÄÉÈÊ [e tutti gli altri]'
ConvertString = 'AAAEEE [e tutti gli altri]'

Ricerca del carattere in AccentString e sostituzione dello stesso indice in ConvertString

HTH

Nella tabella codici 1251, i caratteri sono codificati con 2 byte: uno per il carattere di base e uno per la variazione. Quindi, quando ricodifichi in ASCII, vengono mantenuti solo i caratteri di base.

public string RemoveDiacritics(string text)
{

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

}

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

Sembra che tu l'abbia inchiodato, penso. Un array di byte lungo 128 byte, indicizzato da char & amp; 127, contenente il carattere a 7 bit corrispondente per il carattere a 8 bit.

Hm, perché non cambiare semplicemente la codifica della stringa con iconv?

Dipende molto dalla natura delle stringhe di origine. Se conosci la codifica della stringa e sai che è una codifica a 8 bit, ad esempio ISO Latin 1 o simile, è sufficiente un semplice array statico:

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

D'altra parte, se si dispone di una codifica diversa o se si utilizzano stringhe con codifica UTF-8, è possibile trovare le funzioni nel progetto ICU molto utile.

C'è un articolo su CodeProject che sembra buono.

Anche la conversione utilizzando la tabella codici 1251 mi interessa (vedi altra risposta).

Non mi piacciono le tabelle di conversione, dal momento che il numero di caratteri in Unicode è così grande che ti manca facilmente uno.

Penso che tu l'abbia già inchiodato sulla testa. Dato il tuo dominio limitato, una matrice di conversione o hash è la soluzione migliore. Non ha senso creare qualcosa di complesso per provare a farlo automagicamente.

Un array di ricerca è probabilmente il modo più semplice e veloce per ottenere questo risultato. Questo è un modo in cui puoi convertire dire, ASCII in EBCDIC.

I 128 caratteri superiori non hanno significati standard. Possono assumere diverse interpretazioni (pagine di codice) a seconda della lingua dell'utente.

Ad esempio, vedi portoghese contro francese canadese

A meno che tu non conosca la tabella codici, la tua " traduzione " a volte sarà sbagliato.

Se si intende assumere una determinata tabella codici (ad esempio la tabella codici IBM originale), allora funzionerà un array di traduzione, ma per i veri utenti internazionali, si sbaglierà molto.

Questo è uno dei motivi per cui unicode è preferito rispetto al vecchio sistema di pagine di codice.

A rigor di termini, ASCII è solo 7 bit.

Prova il uni2ascii .

Uso questa funzione per correggere una variabile con accenti da passare a una funzione soap da 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 all'interno della funzione soap lo faccio (per la variabile Nome file):

FileName = HttpContext.Current.Server.HtmlDecode(FileName)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top