24
4

4 に答える 4

30

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 の意見は正しいです。

于 2009-12-12T05:33:34.263 に答える
8

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 に報告する必要があるかどうかです。

于 2013-03-19T12:52:50.267 に答える
3

あなたの最善の策は、ルックアップテーブルを作成することだと思います。

于 2009-12-11T22:22:53.753 に答える