Pergunta

Existe uma rotina disponível no Delphi 2007 para converter os caracteres na gama alta da tabela ANSI (> 127) para os seus entes equivalentes em ASCII puro (<= 127) de acordo com a localidade (página de código)?

Eu sei que alguns caracteres não pode traduzir bem, mas a maioria pode, esp. na faixa de 192-255:

  • A ? A
  • A ? a
  • E ? E
  • E ? e
  • C ? C
  • ç ? c
  • - (traço) ? - (hífen - que pode ser mais complicado)
  • - (travessão) ? - (hífen)
Foi útil?

Solução

WideCharToMultiByte faz mapeamento de melhor ajuste para quaisquer caracteres que não são suportadas pelo conjunto de caracteres especificado, incluindo diacríticos decapagem. Você pode fazer exatamente o que você quer usando isso e passando 20127 (US-ASCII) como a página de código.

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;

Chamada que com os seus exemplos produz resultados que você está procurando, incluindo o caso emdash-a-menos, que eu não acho que é tratado por sugestão de Jeroen se converter ao formulário de Normalização D. Se você queria tomar esse abordagem, Michael Kaplan tem um post blogue os diacríticos explicitamente discute decapagem (em vez de normalização em geral), mas usa C # e uma API que foi introduz no Vista. Você pode obter algo semelhante usando a API FoldString (qualquer versão WinNT).

É claro que se você só está fazendo isso para um conjunto de caracteres, e você quer evitar a sobrecarga de converter de e para um WideString, Padu é correto que um simples loop e uma tabela de pesquisa seria tão eficaz.

Outras dicas

Apenas para estender a resposta de Craig para Delphi 2009:

Se você usar o Delphi 2009 e mais recente, você pode usar um código mais legível com o mesmo resultado:

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

Infelizmente, este código funciona somente no MS Windows. No Mac, os acentos não são substituídos por melhores equipada personagens, mas por pontos de interrogação.

Obviamente, Delphi usa internamente WideCharToMultiByte no Windows enquanto no Mac iconv é usado (ver LocaleCharsFromUnicode em system.pas). A questão é se esse comportamento diferente no OS diferente deve ser considerado como bug e relatado para CodeCentral.

Eu acredito que sua melhor aposta é a criação de uma tabela de pesquisa.

O que você está procurando é a normalização.

Michael Kaplan escreveu um href="http://www.siao2.com/2007/08/17/4424917.aspx" rel="nofollow noreferrer"> agradável blogue artigo .

Ele não resolve imediatamente o seu problema, mas pontos você na direção certa.

- jeroen

scroll top