【问题标题】:Convert Hi-Ansi chars to Ascii equivalent (é -> e)将 Hi-Ansi 字符转换为等效的 Ascii (é -> e)
【发布时间】:2010-12-25 20:38:27
【问题描述】:

Delphi 2007 中是否有一个例程可以根据语言环境(代码页)将 ANSI 表 (>127) 高范围内的字符转换为纯 ASCII (

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

  • À → A
  • à → 一个
  • Ë → E
  • ë → e
  • Ç → C
  • ç → c
  • – (短划线) → - (连字符 - 这可能更棘手)
  • — (破折号) → - (连字符)

【问题讨论】:

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


    【解决方案1】:

    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 的建议不会处理这种情况。如果你确实想这样做方法,Michael Kaplan 有一个 blog post 明确讨论剥离变音符号(而不是一般的规范化),但它使用 C# 和 Vista 中引入的 API。您可以使用 FoldString api(任何 WinNT 版本)获得类似的东西。

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

    【讨论】:

    • 谢谢克雷格。这是比查找更通用的解决方案。它的幻数有错别字,所以我更正了它并改用了一个常数。但无论如何,它适用于 D2007 和 D2009。
    • 我们注意到这一点,'β'(unicode 1E9E 拉丁大写字母 s)没有被转换,所以我们事先这样做: StringReplace(aStr, 'β', 'SS ', [rfReplaceAll])
    【解决方案2】:

    只是为了扩展 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。

    【讨论】:

    • iconv 确实有一个//TRANSLIT 选项,但LocaleCharsFromUnicode() 没有使用它。
    【解决方案3】:

    我相信您最好的选择是创建一个查找表。

    【讨论】:

    • 另外,如果你在使用一个不错的正则表达式库和 delphi,也可以使用它,但它仍然是一种查找表。
    • 谢谢帕杜。那正是我所想。尽管如此,我还是会接受克雷格的回答,因为它更通用。
    【解决方案4】:

    您正在寻找的是规范化。

    Michael Kaplan 写了一个nice blog article about normalization。

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

    --杰罗恩

    【讨论】:

    • NFKD + 去除组合标记在很多时候都有效。但是有ÆÐØÞßæðøþ这样的字符是不会分解的,需要手动处理。
    猜你喜欢
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 2018-11-04
    • 2011-07-05
    • 1970-01-01
    相关资源
    最近更新 更多