在德尔福 7 中获取字符值



我正在用Delphi 7制作一个程序,它应该将Unicode字符串编码为html实体字符串。例如,"ABCģķī"将导致"ABCģķī">

现在 2 件基本的事情:

  1. Delphi 7 是非 Unicode,所以我不能直接在代码中编写 unicode 字符来编码它们。
  2. 代码页
  3. 由 255 个条目组成,每个条目包含一个特定于该代码页的字符,前 127 个除外,这些字符对于所有代码页都是相同的。

那么 - 我如何获得 1-255 范围内的字符值?

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

还有其他返回字符值的方法吗?任何帮助表示赞赏

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

我会考虑两种Unicode方法:WideString和UTF-8。

宽字符串的优点是它是Windows的"本机",如果您需要使用Windows API调用,这会有所帮助。缺点是存储空间,并且它们(如 UTF-8(可能需要多个 WideChar 来编码完整的 Unicode 空间。

通常首选 UTF-8。与 WideString 一样,这是一种多字节编码,因此特定的 unicode "代码点"可能需要字符串中的几个字节来对其进行编码。仅当您对字符串进行大量逐字符处理时,这才是一个问题。

@DavidHeffernan评论(正确(宽字符串在某些情况下可能更紧凑。但是,我只推荐 UTF-16 只有在您绝对确定您的编码文本确实会更紧凑(不要忘记标记!(的情况下,这种紧凑性对您来说非常重要。

在 HTML

4 中,数字字符引用相对于 HTML 使用的字符集。 无论该字符集是通过 <meta> 标记在 HTML 本身中指定的,还是通过 HTTP/MIME Content-Type标头或其他方式在带外指定,都无关紧要。因此,只有当 HTML 使用 UTF-16 时,"ABC&#291;&#311;&#299;"才是"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 数据分配给使用 UTF-16 的WideString(这是 Delphi 7 本机支持的唯一 Unicode 字符串类型(,然后:

  1. 如果您需要 HTML 4:

    A. 如果 HTML 字符集不是 UTF-16,则使用 WideCharToMultiByte()(或等效项(将WideString转换为该字符集,然后遍历结果值,按原样输出非保留字符和保留值的字符引用,使用 IntToStr() 表示十进制表示法或IntToHex()表示十六进制表示法。

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

  2. 如果您需要 HTML 5:

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

    B. 否则,使用 WideStringToUCS4String()WideString转换为 UTF-32,然后遍历输出未保留代码点的结果值,按原样输出未保留的代码点和保留代码点的字符引用,使用 IntToStr() 表示十进制表示法或IntToHex()表示十六进制表示法。

如果我正确理解了 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;

最新更新