4 に答える
WideCharToMultiByteは、分音記号の削除など、指定された文字セットでサポートされていない文字に対して最適なマッピングを行います。それを使用し、コードページとして 20127 (US-ASCII) を渡すことで、まさにあなたが望むことを行うことができます。
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;
あなたの例でそれを呼び出すと、emdash-to-minus ケースを含む、探している結果が生成されます。これは、正規化形式 D に変換するという Jeroen の提案によって処理されるとは思いません。そのアプローチを取りたい場合は、Michael Kaplan のブログ投稿では、(一般的な正規化ではなく) 分音符号の削除について明示的に説明していますが、Vista で導入された C# と API を使用しています。FoldString API (任意の WinNT リリース) を使用して同様のものを取得できます。
もちろん、これを 1 つの文字セットに対してのみ行っており、WideString との間の変換によるオーバーヘッドを回避したい場合は、単純な for ループとルックアップ テーブルが同様に効果的であるという Padu の意見は正しいです。
Delphi 2009に対するCraigの回答を拡張するだけです:
Delphi 2009 以降を使用している場合は、より読みやすいコードを使用して同じ結果を得ることができます。
function OStripAccents(const aStr: String): String;
type
USASCIIString = type AnsiString(20127);//20127 = us ascii
begin
Result := String(USASCIIString(aStr));
end;
残念ながら、このコードは MS Windows でしか機能しません。Mac では、アクセントは最適な文字ではなく疑問符に置き換えられます。
明らかに、Delphi は内部的に Windows では WideCharToMultiByte を使用しますが、Mac では iconv が使用されます (System.pas の LocaleCharsFromUnicode を参照)。問題は、異なる OS でのこの異なる動作をバグと見なし、CodeCentral に報告する必要があるかどうかです。
あなたの最善の策は、ルックアップテーブルを作成することだと思います。