Pregunta

¿Existe una disposición habitual en Delphi 2007 para convertir los caracteres en el rango alto de la tabla ANSI (> 127) a sus seres equivalentes en ASCII puro (<= 127) de acuerdo con una configuración regional (página de códigos)?

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

  • A A
  • a
  • e E
  • e e
  • c C
  • c c
  • - (guión corto) - (guión - que puede ser más complicado)
  • - (guión largo) - (guión)
¿Fue útil?

Solución

WideCharToMultiByte hace mapeo de mejor ajuste para los caracteres que no son compatibles con el juego de caracteres especificado, incluyendo diacríticos de desbroce. Usted puede hacer exactamente lo que quiere mediante el uso de 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 se quería dar ese enfoque, Michael Kaplan tiene una blog los diacríticos explícitamente discute pelado (en vez de normalización en general), sino que utiliza C # y una API que se introduce en Vista. Se puede conseguir algo similar utilizando la API FoldString (cualquier versión de WinNT).

Por supuesto, si sólo está haciendo esto por un conjunto de caracteres, y se quiere evitar la sobrecarga de la conversión hacia y desde un WideString, Padu es correcto que un simple bucle y una tabla de búsqueda podría ser igual de eficaz.

Otros consejos

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 sólo en MS Windows. En Mac, los acentos no son reemplazados por personajes de mejor ajuste, sino por signos de interrogación.

Obviamente, Delphi utiliza internamente WideCharToMultiByte en Windows, mientras que en Mac iconv se utiliza (ver LocaleCharsFromUnicode en System.pas). La pregunta es si este comportamiento diferente en diferentes sistemas operativos se debe considerar como error e informó a CodeCentral.

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

Lo que se busca es la normalización.

Michael Kaplan escribió un artículo en el blog agradable sobre la normalización .

No resuelve su problema de inmediato, sino que apunta en la dirección correcta.

- Jeroen

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top