时间旅行  

遗憾的是当我再次感受 AI 协助编程,通义豆包等还是不如 ChatGPT,无论是 C 还是 Python,在修正 Bug 方面存在不小差距。

评论 0

例子一:Windows 上总有不少的窗口喜欢自己弹出来,写了一个可配置的程序,按窗口 Class 、窗口名称关闭它们。ChatGPT C 和 Python 都一遍过。

例子二:🕮 的 Unicode 编码是 1F56E,文本编辑器 EverEdit 实现了 Windows Script Host 的 COM 接口,可以像类似浏览器 DOM 一样改变其中文本的内容,比如 App.ActiveDoc.Insert(s); 可以插入一个字符串 s。我有一个问题,就是当使用这个脚本插入常规字符时是正常的,而插入 ‘🕮’ 字符就会插入乱码,需要把 ‘🕮’ 写为 “\uD83D\uDD6E” 才正常,我的疑问在于,为什么 ‘\uF09F\u95AE’ 同样作为 ‘🕮’ 的 Unicode 表示,却无法正确插入呢?

var s = '🕮';
s = '\uF09F\u95AE';
s = "\uD83D\uDD6E";
App.ActiveDoc.Insert(s);

ChatGPT 可以正常回答,我认为它解答的非常到位,甚至还可以帮我修改为 Textile:


您的问题涉及 Unicode 编码的不同表示方式以及它们在不同编码环境下的处理方式。以下是详细的解释:

为什么 \uF09F\u95AE 无法正确插入 🕮

您的问题涉及 Unicode 编码的不同表示方式及其在不同编码环境下的处理方式。以下是详细的解释:

Unicode 的不同表示方式

  • Unicode 的代码点 🕮 是 U+1F56E
  • 由于其代码点超出了 *Basic Multilingual Plane (BMP, 0x00000xFFFF)*,在 UTF-16 表示时需要被拆分为两个 16 位的代码单元,称为**代理对**(surrogate pairs):
    • 高代理(high surrogate):@\uD83D@
    • 低代理(low surrogate):@\uDD6E@
    • 所以 🕮UTF-16 中表示为 *@\uD83D\uDD6E@*。
  • \uF09F\u95AE 是 🕮 的 UTF-8 编码形式(@F0 9F 95 AE@)直接写成 Unicode 转义,但这不符合 UTF-16 的编码规则,因此可能被错误地解释。

为什么 \uF09F\u95AE 不起作用

1. 不符合 UTF-16 规范:

  • \uF09F\u95AE 被单独解释成两个独立的 16 位值,它们并不构成有效的代理对。
  • UTF-16 的规则中:
    • 每个高代理必须在 \uD800\uDBFF 之间。
    • 每个低代理必须在 \uDC00\uDFFF 之间。
  • \uF09F\u95AE 显然不在此范围,因此解析时会被当作两个无意义的字符,而不是一个有效的 Unicode 字符。

2. 文本编辑器对字符串的处理:

  • 当您传入 \uF09F\u95AE 时,EverEdit 的脚本解析器会按照 UTF-16 解码,而 \uF09F\u95AE 不符合 UTF-16 的规则,因此被当作无效字符。
  • \uD83D\uDD6E 是正确的代理对,会被解析为 U+1F56E,因此能够正确显示。

如何验证 UTF-16 编码

以下代码展示了如何验证 🕮 的编码是否正确:

char = '🕮'

# UTF-16 代理对
utf16 = char.encode('utf-16', 'surrogatepass')
print(utf16.hex())  # 输出:d83ddd6e

# UTF-8 表示
utf8 = char.encode('utf-8')
print(utf8.hex())  # 输出:f09f95ae

为什么必须使用 \uD83D\uDD6E

这是因为:

  • \uD83D\uDD6EUTF-16 的合法表示,符合 Windows Script Host 和 EverEdit 的解析规则。
  • \uF09F\u95AEUTF-8 编码的 Unicode 转义,在只支持 UTF-16 的解析环境中无法被正确解释。

解决方案

如果需要动态处理插入 Unicode 字符,您可以在脚本中确保将代码点转换为合法的 UTF-16 代理对:

var codePoint = 0x1F56E; // Unicode 代码点
var surrogatePair = String.fromCodePoint(codePoint); // 转换为 UTF-16
App.ActiveDoc.Insert(surrogatePair); // 插入

这样可以确保任何超出 BMP 的 Unicode 字符都能够被正确插入。

总结

\uF09F\u95AE 表示的是 UTF-8 的编码值,而 EverEdit 使用的是 UTF-16 编码的代理对。如果需要插入正确的 Unicode 字符,需要将代码点转换为 UTF-16 的代理对,例如使用 \uD83D\uDD6E 或动态生成代理对。这就是为什么 \uF09F\u95AE 无法正常工作的根本原因。

作者
分类 编程技术


评论

这篇文章目前没有评论。

发表评论

在下面发表您的评论 标记 * 的字段为必填项。提交评论前请预览。