如何检查 Javascript 中 Unicode 字符串的相等性?

Posted

技术标签:

【中文标题】如何检查 Javascript 中 Unicode 字符串的相等性?【英文标题】:How do I check equality of Unicode strings in Javascript? 【发布时间】:2011-10-29 04:45:30 【问题描述】:

我在 javascript 中有两个字符串:"_strange_chars_µö¬é@zendesk.com.eml" (f1) 和 "_strange_chars_µö¬é@zendesk.com.eml" (f2)。乍一看,它们看起来是一样的(实际上,在 *** 上,它们可能是一样的;我不确定当它们被粘贴到这样的表单中时会发生什么。)然而,在我的应用程序中,

f1[16] // ö
f2[16] // o
f1[17] // ¬
f2[17] // ̈

也就是说,f1 使用 ö 字符,f2 使用 o 和变音符号 ¨ 作为单独的字符.我可以做哪些比较来显示这两个字符串“相等”?

【问题讨论】:

一个解决方案——也许是唯一的一个——是“规范化”(在 Unicode 意义上)这两个字符串,但我还没有找到一个库或函数。 您确定已在元标记中声明了 UTF-8 吗? 好问题,@cwallenpoole。我不是,但我现在要仔细检查。我已经描述的两个字符串肯定 can 都是有效的 Unicode,但我不确定它们 @cwallenpoole 页面声明<meta charset="utf-8">,表单(文件输入是第一个字符串的来源)声明accept-charset="UTF-8"。当然,HTTP 请求和响应也是 UTF-8。我认为这只是使用不同 Unicode 规范化的不同系统(浏览器与服务器)的情况。 (或者使用与不使用规范化。) 【参考方案1】:

f1 使用 ö 字符,f2 使用 o 和变音符号 ¨ 作为单独的字符。

f1 在 Normal Form C(已组合)和 f2 在标准形式 D(已分解)中。一般来说,Normal Form C 在 Windows 和 Web 上最常见,Unicode FAQ 将其描述为“一般文本的最佳形式”。不幸的是,Apple 世界为了与众不同而选择了 Normal Form D。

根据Unicode equivalence 的规则,这些字符串在规范上是等效的。

我可以做哪些比较来显示这两个字符串“相等”?

通常,您将两个字符串转换为您选择的一种范式,然后比较它们。例如在 Python 中:

>>> import unicodedata
>>> a= u'\u00F6'  # ö composed
>>> b= u'o\u0308' # o then combining umlaut
>>> unicodedata.normalize('NFC', a)==unicodedata.normalize('NFC', b)
True

类似地,Java 有 Normalizer 类,.NET 有 String.Normalize,并且可能语言具有可用于也提供此功能的 ICU 库的绑定。

不幸的是,JavaScript 没有原生 Unicode 规范化能力。这意味着:

自己动手,在大型 Unicode 数据表中使用 JavaScript 覆盖所有内容(参见例如 here 示例实现);或

将其发送回服务器端(例如通过 XMLHttpRequest),在那里您可以使用配备更好的语言来执行此操作。

【讨论】:

您关于 Apple 的陈述完全不真实。 Apple 的 HSF+ 文件系统出于完全合理的原因使用 (whilom-)NFD。预组合字符被 Unicode 视为兼容字符,用于与旧编码进行往返,并且 不是 供内部使用的首选形式,正如您在此处所误解的那样。标准建议是将 NFD 所有传入数据作为您使用它之前的第一步,并将 NFC 所有传出数据作为您分道扬镳之前的最后一步。单身人士因此发生了变异,但无论如何这最终都会发生。 @tchrist:对组合字符的引用是“兼容性”?它们肯定不是字面意义上的兼容性,因为毕竟有范式 KC。官方FAQ 更喜欢NFC/NFKC,提到分解仅对内部处理有用。但是 HFS+ 和 UFS 上的文件名只是内部的,这些数据会返回到应用程序,这使得其中许多应用程序崩溃了。 OS X 文件系统不会按照您的建议将文件名标准化为 NFC。 (我个人认为不区分大小写和不区分组合都是文件系统中不受欢迎的功能,但至少在 Windows 的情况下,您会得到最初放入的案例。) JS 现在有这个 - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。不幸的是 IE11 不支持这一点,虽然你可以使用像 github.com/walling/unorm 这样的外部库,但它在前端的使用量很大

以上是关于如何检查 Javascript 中 Unicode 字符串的相等性?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查字节数组是不是包含 Java 中的 Unicode 字符串?

如何获取 Javascript 中字符的 Unicode 代码点?

如何使用 JavaScript/jQuery 从 HTML 中获取符号的 unicode/hex 表示?

检查 unicode 值是不是在 Erlang 二进制字符串中?

如何检查字节数组是否包含Java中的Unicode字符串?

javascript - 如何将unicode字符串转换为ascii [重复]