Delphi 将Hi Ansi字符转换为Ascii等效字符(é;->;e)

Delphi 将Hi Ansi字符转换为Ascii等效字符(é;->;e),delphi,character-encoding,ascii,delphi-2007,non-ascii-characters,Delphi,Character Encoding,Ascii,Delphi 2007,Non Ascii Characters,Delphi 2007中是否有一个例程可用于将ANSI表(>127)中的高位字符转换为纯ASCII中的等效字符(我认为最好的办法是创建查找表。您需要的是规范化 迈克尔·卡普兰写了一篇文章 它不会立即解决您的问题,但会为您指明正确的方向 --jeroen对指定字符集不支持的任何字符进行最佳匹配映射,包括去除变音符号。您可以使用它并将20127(US-ASCII)作为代码页传递,从而完全实现您想要的操作 function BestFit(const AInput: AnsiString): Ansi

Delphi 2007中是否有一个例程可用于将ANSI表(>127)中的高位字符转换为纯ASCII中的等效字符(我认为最好的办法是创建查找表。

您需要的是规范化

迈克尔·卡普兰写了一篇文章

它不会立即解决您的问题,但会为您指明正确的方向

--jeroen对指定字符集不支持的任何字符进行最佳匹配映射,包括去除变音符号。您可以使用它并将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到减号的情况,我认为Jeroen建议转换为规范化形式D不会处理这个问题。如果你真的想采用这种方法,Michael Kaplan有一个明确的方法来讨论剥离变音符号(而不是一般的规范化),但它使用C#和Vista中引入的API。您可以使用FoldString API(任何WinNT版本)获得类似的结果


当然,如果您只对一个字符集执行此操作,并且您希望避免从宽字符串转换到宽字符串的开销,那么Padu正确地认为简单的for循环和查找表同样有效。

仅扩展Craig对Delphi 2009的回答:

如果使用Delphi 2009及更新版本,则可以使用可读性更高的代码,结果相同:

function OStripAccents(const aStr: String): String;
type
  USASCIIString = type AnsiString(20127);//20127 = us ascii
begin
  Result := String(USASCIIString(aStr));
end;
不幸的是,这段代码只在微软的Windows上运行。在Mac上,重音并没有被最合适的字符所取代,而是被问号所取代

显然,Delphi在Windows上内部使用WideChartMultiByte,而在Mac上则使用iconv(请参阅System.pas中的LocaleCharsFromUnicode)。
问题是,不同操作系统上的这种不同行为是否应该被视为bug并报告给CodeCentral。

此外,如果您使用delphi的一个不错的正则表达式库,也可以使用它,但它仍然是一种查找表。谢谢Padu。这是我的想法。不过我还是会接受Craig的答案,因为它更通用。Thanks Craig。这是一个比查找更通用的解决方案。它的幻数有一个输入错误,所以我更正了它,并使用了一个常量。但无论如何,它对D2007和D2009都有效。我们注意到,在这方面,“β”(unicode 1E9E拉丁文大写字母夏普s)没有转换,所以我们事先做了这个:StringReplace(aStr,'β','SS',[rfReplaceAll])NFKD+去除组合标记在很多情况下都能起作用。然而,有些字符,如
不分解,必须手动处理。iconv有
//translatit
选项,但
LocaleCharsFromUnicode()
不使用它。