结合急性重音和结合急性音调标记与如何正常化的区别

时间:2017-09-24 17:46:20

标签: unicode encoding diacritics non-ascii-characters utf

所以我有一个应用程序(让我们称之为客户端),它使用带有Diacritic / Accents的字符串。此应用程序需要使用具有变音符号的这些字符串向另一个应用程序(让我们称之为Web服务)发出请求。开发这个其他应用程序是为了接收这样的字符串。

但是当客户端向Web服务发出请求时,事情不会按预期工作。在调查中,我意识到问题在于变音符号。

基本上,似乎某些肉眼看来相同的变音符号具有不同的Unicode表示。

例如,通常称为急性重音:我意识到有一个具有01401 https://unicodelookup.com/#01401/1的八进制表示,另一个具有01501的八进制表示https://unicodelookup.com/#01501/1

八进制表示为01401的那个被称为组合急性重音,而具有01501的那个被称为组合急性音标。因此,除了具有不同的表示之外,它们看起来也是语义上不同的。

这是我遇到的问题的根源。客户端使用变音符号创建其字符串,称为组合锐音标记,而客户端期望字符串与组合锐音

所以问题是,这两者究竟有什么区别? (谷歌搜索似乎没有出现任何有用的东西)我怎么可能在这两个表示之间“正常化/转换”(因为我认为这是需要做的事情)在其他方面,以便客户能够成功调用到网络服务。

更新 我可以提一下,客户端发送的字符串是从浏览器发送的,因此我可以使用unicodelookup.com上的工具复制字符串并进行查找。

我只是进行相同的查找,但是来自另一台计算机。之前,我在Mac上查找。当我进行查找时(通过从浏览器URL复制并将字符粘贴到unicodelookup.com中),返回组合急性音标的内容现在返回为组合急性重音 < / p>

以为我应该提一下这个观察。

1 个答案:

答案 0 :(得分:0)

您可以在浏览器中使用 JavaScript's String.prototype.normalize method 进行 Unicode 规范化(从 ES6 开始)。

当接受 Unicode 用户输入时,在涉及任何类型的比较时都应该进行规范化,这不仅仅是您发现的原因。您应该使用哪种规范化形式取决于用例,但 NFC 是一个很好的默认形式(这就是 .normalize() 所做的)。

您提到的组合标记是“规范等价的”,因此使用相同的形式(在这种特定情况下哪个无关紧要)将两者标准化将始终使它们相等:

var accented = "a\u0300"  // "à"
var toneMarked = "a\u0340"  // "à"

accented === toneMarked  // false

accented === accented.normalize("NFD")  // true, this is already the canonical decomposed form
toneMarked === toneMarked.normalize("NFD")  // false
accented === toneMarked.normalize("NFD")  // true

accented.normalize("NFC") === toneMarked.normalize("NFC")  // true
accented.normalize() === toneMarked.normalize()  // equivalent to above

// Also have to consider precomposed characters! (single code point)

var composed = "à"

composed === accented  // false

composed.normalize("NFD") === accented  // true

composed === composed.normalize()  // true, this is already the canonical composed form
composed === accented.normalize() && composed === toneMarked.normalize()  // true

请注意,通常应在后端执行规范化,因为您不能对来自用户客户端的数据进行任何假设。