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

Fra*_*ois 23 delphi ascii character-encoding delphi-2007 non-ascii-characters

在Delphi 2007中是否有例程可以根据区域设置(代码页)将ANSI表(> 127)的高范围内的字符转换为纯ASCII(<= 127)中的等效字符?

我知道有些字符不能很好地翻译,但大多数字符都可以,尤其是.在192-255范围内:

  • ÀA
  • àa
  • ËE
  • ëe
  • ÇC
  • çc
  • - (简称)- (连字符 - 可能比较棘手)
  • - (em dash)- (连字符)

Zoë*_*son 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;
Run Code Online (Sandbox Code Playgroud)

用您的示例调用它会产生您正在寻找的结果,包括emdash-to-minus案例,我认为这不是由Jeroen转换为规范化形式D的建议处理的.如果您确实想采用这种方法,Michael Kaplan有一篇博文,明确讨论了剥离变音符号(而不是一般的标准化),但它使用了C#和Vista中引入的API.您可以使用FoldString api(任何WinNT版本)获得类似的东西.

当然,如果你只是为一个字符集做这个,并且你想避免转换到WideString和从WideString转换的开销,Padu是正确的,一个简单的for循环和一个查找表将同样有效.


oxo*_*oxo 7

只是为了扩展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;
Run Code Online (Sandbox Code Playgroud)

不幸的是,此代码仅适用于MS Windows.在Mac上,重音不是由最合适的字符替换,而是由问号代替.

显然,Delphi在Windows内部使用WideCharToMultiByte,而在Mac上使用iconv(参见System.pas中的LocaleCharsFromUnicode).问题是,是否应将不同操作系统上的这种不同行为视为错误并向CodeCentral报告.