在Delphi 7中获取char值

时间:2013-12-03 09:43:33

标签: delphi unicode delphi-7 html-entities html-encode

我正在Delphi 7中创建一个程序,它应该将unicode字符串编码为html实体字符串。 例如,“ABCģķī”会产生“ABCģķī

现在有两个基本的东西:

  1. Delphi 7是非Unicode的,所以我不能直接在代码中编写unicode字符来编码它们。
  2. 代码页由255个条目组成,每个条目都包含一个特定于该代码页的字符,除了前127个字符,对于所有代码页都是相同的。
  3. 所以 - 如何获得char的值,即1-255范围?

    我尝试Ord(Integer),但它也返回超过255的值。基本上,一切都很好(A返回65,等等),直到我的字符串到达​​非拉丁语unicode。

    还有其他方法可以返回char值吗?任何帮助表示赞赏

3 个答案:

答案 0 :(得分:1)

我建议你避免像瘟疫一样的代码页。

我认为有两种Unicode方法:WideString和UTF-8.

Widestrings的优势在于它是Windows的“原生”,如果您需要使用Windows API调用,这将有所帮助。缺点是存储空间,它们(如UTF-8)可能需要多个WideChars来编码完整的Unicode空间。

UTF-8 is generally preferable。与WideStrings一样,这是一个多字节编码,因此特定的unicode“代码点”可能需要字符串中的几个字节来对其进行编码。如果您对字符串进行大量逐个字符处理,这只是一个问题。

@DavidHeffernan评论(correctly)在某些情况下,WideStrings 可能更紧凑。但是,我只推荐UTF-16,只要你完全确定你的编码文本真的更紧凑(不要忘记标记!),这种紧凑性对你来说非常重要。

答案 1 :(得分:1)

在HTML 4中,数字字符引用与HTML使用的字符集相关。是通过<meta>标记在HTML本身中指定了字符集,还是通过HTTP / MIME Content-Type标头或其他方式指定带外字符集,这无关紧要。因此,"ABC&#291;&#311;&#299;"只有在HTML使用UTF-16时才能准确表示"ABCģķī"。如果HTML使用的是UTF-8,则正确的表示形式可能是"ABC&#196;&#163;&#196;&#183;&#196;&#171;""ABC&#xC4;&#xA3;&#xC4;&#xB7;&#xC4;&#xAB;"。大多数其他字符集不支持这些特定的Unicode字符。

在HTML 5中,数字字符引用包含原始Unicode代码点值,而不管HTML使用的字符集。因此,"ABCģķī"将表示为"ABC#291;&#311;&#299;""ABC&#x0123;&#x0137;&#x012B;"

因此,要回答您的问题,您首先要做的是决定是否需要使用HTML 4或HTML 5语义进行数字字符引用。然后,您需要将Unicode数据分配给WideString(这是Delphi 7本身支持的唯一Unicode字符串类型),它使用UTF-16,然后:

  1. 如果您需要HTML 4:

    一个。如果HTML字符集不是UTF-16,则使用WideCharToMultiByte()(或等效的)将WideString转换为该字符集,然后循环生成输出未保留字符的结果值和保留字符引用值,使用IntToStr()表示十进制表示法,或IntToHex()表示十六进制表示法。

    B中。如果HTML字符集是UTF-16,则只需循环遍历WideChar中的每个WideString,按原样输出未保留字符和保留值的字符引用,使用IntToStr()表示十进制表示法或IntToHex()表示十六进制表示法。

  2. 如果您需要HTML 5:

    一个。如果WideString不包含任何代理项对,则只需循环遍历WideChar中的每个WideString,使用{{1}按原样输出未保留字符和保留值的字符引用用于十进制表示法或IntToStr()表示十六进制表示法。

    B中。否则,使用IntToHex()WideString转换为UTF-32,然后循环输出保留代码点的未保留代码点的结果值和保留代码点的字符引用,使用WideStringToUCS4String()表示十进制表示法或{ {1}}表示十六进制表示法。

答案 2 :(得分:0)

如果我正确地理解了OP,我会把它留在这里。

function Entitties(const S: WideString): string;
var
  I: Integer;
begin
  Result := '';
  for I := 1 to Length(S) do
  begin
    if Word(S[I]) > Word(High(AnsiChar)) then
      Result := Result + '#' + IntToStr(Word(S[I])) + ';'
    else
      Result := Result + S[I];
  end;
end;