我正在用Delphi 7制作一个程序,它应该将Unicode字符串编码为html实体字符串。例如,"ABCģķī
"将导致"ABCģķī
">
现在 2 件基本的事情:
- Delphi 7 是非 Unicode,所以我不能直接在代码中编写 unicode 字符来编码它们。 代码页
- 由 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 只有在您绝对确定您的编码文本确实会更紧凑(不要忘记标记!(的情况下,这种紧凑性对您来说非常重要。
4 中,数字字符引用相对于 HTML 使用的字符集。 无论该字符集是通过 <meta>
标记在 HTML 本身中指定的,还是通过 HTTP/MIME Content-Type
标头或其他方式在带外指定,都无关紧要。因此,只有当 HTML 使用 UTF-16 时,"ABCģķī"
才是"ABCģķī"
的准确表示。 如果 HTML 使用 UTF-8,则正确的表示形式将是 "ABCģķī"
或 "ABCģķī"
。 大多数其他字符集不支持这些特定的 Unicode 字符。
在 HTML 5 中,数字字符引用包含原始 Unicode 代码点值,而不考虑 HTML 使用的字符集。 因此,"ABCģķī"
将表示为 "ABC#291;ķī"
或 "ABCģķī"
。
因此,要回答您的问题,您要做的第一件事是确定是否需要对数字字符引用使用 HTML 4 或 HTML 5 语义。 然后,您需要将 Unicode 数据分配给使用 UTF-16 的WideString
(这是 Delphi 7 本机支持的唯一 Unicode 字符串类型(,然后:
如果您需要 HTML 4:
A. 如果 HTML 字符集不是 UTF-16,则使用
WideCharToMultiByte()
(或等效项(将WideString
转换为该字符集,然后遍历结果值,按原样输出非保留字符和保留值的字符引用,使用IntToStr()
表示十进制表示法或IntToHex()
表示十六进制表示法。B.如果HTML字符集是UTF-16,那么只需遍历
WideString
中的每个WideChar
,按原样输出未保留字符和保留值的字符引用,使用IntToStr()
表示十进制表示法或IntToHex()
表示十六进制表示法。如果您需要 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;