22

¿Hay una rutina disponible en Delphi 2007 para convertir los caracteres en el rango alto de la tabla ANSI (> 127) a sus equivalentes en ASCII puro (< = 127) de acuerdo con una configuración regional (página de códigos)?Convertir caracteres Hi-Ansi a Ascii equivalente (é -> e)

Sé que algunos caracteres no se pueden traducir bien, pero la mayoría sí, especialmente. en el rango de 192-255:

  • ÀUn
  • aun
  • ËE
  • ëe
  • ÇC
  • çc
  • -(en guión)-(guión - que puede ser más complicado)
  • -(em tablero)-(guión)

Respuesta

27

WideCharToMultiByte hace mapeo de mejor ajuste de los caracteres que no son compatibles con el juego de caracteres especificado, incluyendo diacríticos de desbroce. Puede hacer exactamente lo que quiera utilizando eso y pasando 20127 (US-ASCII) como la página de códigos.

function BestFit(const AInput: AnsiString): AnsiString; 
const 
    CodePage = 20127; //20127 = us-ascii 
var 
    WS: WideString; 
begin 
    WS := WideString(AInput); 
    SetLength(Result, WideCharToMultiByte(CodePage, 0, PWideChar(WS), 
    Length(WS), nil, 0, nil, nil)); 
    WideCharToMultiByte(CodePage, 0, PWideChar(WS), Length(WS), 
    PAnsiChar(Result), Length(Result), nil, nil); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ShowMessage(BestFit('aÀàËëÇç–—€¢Š')); 
end; 

Llamando que con sus ejemplos produce resultados que usted está buscando, incluyendo el caso-emdash-a menos, que no creo que es manejado por la sugerencia de Jeroen para convertir al formulario de normalización D. Si lo hizo quiero tomar ese enfoque, Michael Kaplan tiene un blog post que discute explícitamente los signos diacríticos (en lugar de la normalización en general), pero usa C# y una API que se introdujo en Vista. Puede obtener algo similar utilizando la API FoldString (cualquier versión de WinNT).

Por supuesto, si solo hace esto para un juego de caracteres, y desea evitar que la sobrecarga se convierta en WideString, Padu está en lo cierto al decir que un bucle simple y una tabla de búsqueda serían igual de efectivos .

+0

Gracias Craig. Esa es una solución más genérica que la búsqueda. Tenía un error ortográfico en el número mágico, así que lo corrigí y usé una constante en su lugar. Pero de todos modos, funciona tanto en D2007 como en D2009. –

+0

Una cosa que notamos con esto, es que 'β' (unicode 1E9E letra mayúscula latina s) no se convierte, por lo que hacemos esto de antemano: StringReplace (aStr, 'β', 'SS', [rfReplaceAll]) – PatrickvL

3

creo que la mejor opción es la creación de una tabla de búsqueda.

+0

Además, si está utilizando una biblioteca de expresiones regulares decente con Delphi, también se podría usar, pero todavía es una especie de tabla de búsqueda. –

+0

Gracias Padu. Es lo que pensaba. Sin embargo, aceptaré la respuesta de Craig porque es más genérica. –

1

Lo que está buscando es la normalización.

Michael Kaplan escribió un nice blog article about normalization.

No resuelve su problema de inmediato, pero lo orienta en la dirección correcta.

--jeroen

+1

NFKD + la eliminación de marcas combinadas funciona muchas veces. Sin embargo, hay caracteres como 'ÆÐØÞßæðøþ' que no se descomponen y deben tratarse manualmente. – dan04

7

Sólo para extender la respuesta de Craig para Delphi 2009:

Si utiliza Delphi 2009 y posteriores, se puede utilizar un código más legible con el mismo resultado:

function OStripAccents(const aStr: String): String; 
type 
    USASCIIString = type AnsiString(20127);//20127 = us ascii 
begin 
    Result := String(USASCIIString(aStr)); 
end; 

Por desgracia, este código funciona solo en MS Windows. En Mac, los acentos no se reemplazan por caracteres mejor ajustados, sino por signos de interrogación.

Obviamente, Delphi internamente usa WideCharToMultiByte en Windows, mientras que en Mac se usa iconv (vea LocaleCharsFromUnicode en System.pas). La pregunta es si este comportamiento diferente en diferentes sistemas operativos se debe considerar como un error y se debe informar a CodeCentral.

+0

iconv tiene una opción '// TRANSLIT', pero' LocaleCharsFromUnicode() 'no la usa. –

Cuestiones relacionadas