ruby-on-rails - 西里尔字符串 Я̆ Я̄ Я̈ 在 ruby​​ 和其他编程语言中返回长度 2 而不是 1

标签 ruby-on-rails ruby string utf-8 unicode-normalization

在 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/

相关文章:

ruby-on-rails - 如何使用已构建的 Rails html 模板

ruby - 如何在 Ruby 1.8.7 中将 Microsoft Office "Smart"或 "Curly"引号/撇号转换为 ASCII 或 UTF-8 "Straight"引号/撇号?

mysql - 如何连接查询字符串

ios - CocoaPods 不在 pod 安装时创建 Pods.xcconfig

string - scala,字符串变量处理为字符串而不是正则表达式

java - 如何只删除标点符号但留下重音字母?

ruby-on-rails - searchkick自动完成和建议未按预期工作

ruby-on-rails - 哈希 to_json 和返回不保留哈希作为键?

ruby-on-rails - Heroku 中的 unicorn ?为什么不在开发中?

ruby-on-rails - 通过 searchkick 进行多语言搜索