Unicode 合并急性重音和合并急性声调的区别及如何规范化

Unicode 合并急性重音和合并急性声调的区别及如何规范化,unicode,encoding,diacritics,non-ascii-characters,utf,Unicode,Encoding,Diacritics,Non Ascii Characters,Utf,所以我有一个应用程序(我们称之为客户机),它使用带变音/重音的字符串。此应用程序需要使用这些带变音符号的字符串向另一个应用程序(我们称之为web服务)发出请求。开发另一个应用程序是为了接收这样的字符串 但是,当客户机向web服务发出请求时,事情并不像预期的那样工作。经过调查,我意识到问题在于变音符号 基本上,一些肉眼看起来相同的变音符号有不同的Unicode表示法 例如,通常所说的急性口音:我意识到有一个八进制表示为01401,另一个八进制表示为01501 八进制表示法为01401的一个被称为组

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

但是,当客户机向web服务发出请求时,事情并不像预期的那样工作。经过调查,我意识到问题在于变音符号

基本上,一些肉眼看起来相同的变音符号有不同的Unicode表示法

例如,通常所说的急性口音:我意识到有一个八进制表示为01401,另一个八进制表示为01501

八进制表示法为01401的一个被称为组合急性重音,而带有01501的一个被称为组合急性声调。因此,除了具有不同的表示之外,它们似乎在语义上也不同

这就是我问题的根源。客户端使用变音符号创建其字符串,该变音符号被称为组合急性音调标记,而客户端需要使用组合急性重音的字符串

所以问题是,这两者到底有什么区别?(谷歌搜索似乎没有发现任何有用的东西)以及我如何在这两种表示之间“规范化/转换”(我相信这是需要做的),以使客户端能够成功调用web服务

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

我只是做了同样的查找,但是在不同的计算机上。以前,我在我的Mac电脑上查找。当我进行查找时(通过从浏览器URL复制并将字符粘贴到unicodelookup.com),返回的组合急性音调标记现在返回组合急性重音


我想我应该提到这一点。

您可以在浏览器中使用Unicode规范化(从ES6开始)

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

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

var accented=“a\u0300”//“a”
var toneMarked=“a\u0340”/“à”
重音===音调标记//假
Accenced===Accenced.normalize(“NFD”)//true,这已经是标准分解形式
toneMarked==toneMarked.normalize(“NFD”)//false
重音===toneMarked.normalize(“NFD”)//true
重音.normalize(“NFC”)==toneMarked.normalize(“NFC”)//true
重音.normalize()==toneMarked.normalize()//等同于上述
/还必须考虑预先编写的字符!(单代码点)
var=“a”
合成===重音//假
composited.normalize(“NFD”)==重音//真
composited===composited.normalize()//true,这已经是规范的组合形式
组合===强调的.normalize()&&composited===音调标记的.normalize()//true

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

您可以使用在浏览器中执行Unicode规范化(从ES6开始)

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

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

var accented=“a\u0300”//“a”
var toneMarked=“a\u0340”/“à”
重音===音调标记//假
Accenced===Accenced.normalize(“NFD”)//true,这已经是标准分解形式
toneMarked==toneMarked.normalize(“NFD”)//false
重音===toneMarked.normalize(“NFD”)//true
重音.normalize(“NFC”)==toneMarked.normalize(“NFC”)//true
重音.normalize()==toneMarked.normalize()//等同于上述
/还必须考虑预先编写的字符!(单代码点)
var=“a”
合成===重音//假
composited.normalize(“NFD”)==重音//真
composited===composited.normalize()//true,这已经是规范的组合形式
组合===强调的.normalize()&&composited===音调标记的.normalize()//true

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

查看相关的,我看到组合音调标记U+0341来自越南语,因此您指的是哪个变音符号取决于所讨论的单词来自的语言。unicode标准还规定不鼓励使用0341,而应使用0301(重音)。@KerrekSB感谢您的提醒。请问,实际的语言将如何帮助破译这个问题?让我们假设这门语言实际上是越南语,那么需要做些什么来解决“组合急性口音”和“组合急性声调”之间的区别呢。我是否需要更新客户端/服务上的某些设置,以确保它们处于同步状态?这是字体问题。例如,OTF拥有GSUB a