在 Ruby、Javascript 和 Java(其他我没试过)中,有西里尔字符 Я̆ Я̄ Я̈ 长度 2。当我尝试用这些字符检查字符串的长度时,我得到了错误的输出值。
"Я̈".mb_chars.length
#=> 2 #should be 1 (ruby on rails)
"Я̆".length
#=> 2 #should be 1 (ruby, javascript)
"Ӭ".length
#=> 1 #correct (ruby, javascript)
请注意,字符串以 UTF-8 编码,每个字符都表现为单个字符。
我的问题是为什么会有这样的行为,我怎样才能正确地得到带有这些字符的字符串的长度?
最佳答案
根本问题是 Я̈
实际上是两个代码点:Я
和变音符号是分开的:
'Я̈'.chars
#=> ["Я", "̈"]
通常你会通过 unicode 规范化来解决这类问题,但单凭这一点对你没有帮助,因为 Я̈
或 Я̆
没有单一代码点(但有 Ӭ
).
您可以在检查长度之前去除变音符号:
'Я̆'.gsub(/\p{Diacritic}/, '')
#=> "Я"
'Я̆'.gsub(/\p{Diacritic}/, '').length
#=> 1
您将获得所需的长度,但字符串不会完全相同。这也适用于 Ӭ
之类的东西,它可以由单个代码点表示:
'Ӭ'.length
#=> 1
'Ӭ'.gsub(/\p{Diacritic}/, '')
#=> "Ӭ"
'Ӭ'.gsub(/\p{Diacritic}/, '').length
#=> 1
Unicode 很棒,很棒,它解决了过去困扰我们的许多问题。不幸的是,Unicode 也很可怕和复杂,因为人类语言和字形并不是完全设计出来的。
关于ruby-on-rails - 西里尔字符串 Я̆ Я̄ Я̈ 在 ruby 和其他编程语言中返回长度 2 而不是 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48271858/