所以我有一个应用程序(让我们称之为客户端),它使用带有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>
以为我应该提一下这个观察。
答案 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
请注意,通常应在后端执行规范化,因为您不能对来自用户客户端的数据进行任何假设。