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

时间:2009-12-11 22:10:36

标签: delphi character-encoding ascii delphi-2007 non-ascii-characters

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

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

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

4 个答案:

答案 0 :(得分:28)

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案例,我认为这不是由Jeroen转换为规范化形式D的建议处理的。如果您确实想要这样做方法,迈克尔卡普兰有blog post明确讨论剥离变音符号(而不是一般的标准化),但它使用C#和Vista中引入的API。您可以使用FoldString api(任何WinNT版本)获得类似的东西。

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

答案 1 :(得分: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;

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

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

答案 2 :(得分:3)

我相信你最好的办法是创建一个查找表。

答案 3 :(得分:1)

您正在寻找的是正常化。

迈克尔卡普兰写了nice blog article about normalization

它并没有立即解决您的问题,而是指向正确的方向。

- 的Jeroen