Domanda

Esiste una routine disponibile in Delphi 2007 per convertire i caratteri nella fascia alta della tabella ANSI (> 127) ai loro quelli equivalenti in puro ASCII (<= 127) secondo un locale (tabella codici)?

So che alcuni caratteri non possono tradurre bene, ma la maggior parte può, esp. nel range 192-255:

  • a A
  • a a
  • e E
  • e e
  • C C
  • C c
  • - (trattino) - (trattino - che può essere più difficile)
  • - (lineetta) - (trattino)
È stato utile?

Soluzione

WideCharToMultiByte fa mappatura best-fit per qualsiasi carattere non supportati dal set di caratteri specificato, compresi diacritics stripping. Si può fare esattamente quello che vuoi utilizzando tale e passando 20127 (US-ASCII) come la tabella di codici.

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;

La chiamata che con i tuoi esempi produce risultati che stai cercando, compreso il caso emdash-a-meno, che non credo che viene gestita dal suggerimento di Jeroen per convertire in forma Normalizzazione D. Se avete voglia di prendere quella approccio, Michael Kaplan ha un post i segni diacritici esplicitamente discute di strippaggio (piuttosto di normalizzazione in generale), ma utilizza C # e un'API che era introduce in Vista. È possibile ottenere qualcosa di simile utilizzando l'API FoldString (qualsiasi release WinNT).

Naturalmente se si sta facendo solo questo per un set di caratteri, e si vuole evitare il sovraccarico da convertire da e verso un WideString, Padu è corretto che un semplice ciclo for e una tabella di ricerca sarebbe altrettanto efficace.

Altri suggerimenti

Proprio per estendere la risposta di Craig per Delphi 2009:

Se si utilizza Delphi 2009 e successivi, è possibile utilizzare un codice più leggibile con lo stesso risultato:

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

Purtroppo, questo codice funziona solo su MS Windows. Su Mac, gli accenti non vengono sostituiti da personaggi più dotati, ma da punti interrogativi.

Ovviamente, Delphi usa internamente WideCharToMultiByte su Windows, mentre su Mac iconv viene utilizzato (vedi LocaleCharsFromUnicode in System.pas). La domanda è se questo comportamento diverso sul sistema operativo diverso dovrebbe essere considerata come bug e segnalato per CodeCentral.

Credo che la soluzione migliore è la creazione di una tabella di ricerca.

Quello che state cercando è la normalizzazione.

Michael Kaplan ha scritto un bell'articolo blog su di normalizzazione .

Non risolve immediatamente il problema, ma si punta nella direzione giusta.

- Jeroen

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top