ruby - Ruby 编码替换错误
问题描述
我正在尝试读取一个文本文件,其中包含许多带有重音符号(标点符号)的字符串,并使用 Ruby(不是 On Rails)用那些没有这些重音符号的字符串填充数据库。
例如我有:
J'ai été mise au courant des éventualités à temps。
我想将整行替换为以下字符串:
J'ai ete mise au courant des eventualites a temps。
因此,为此我找到了应该有效的方法:
def convert_to_ascii(s)
undefined = ''
fallback = { 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A',
'Å'=>'A', 'Æ'=>'AE', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I',
'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U',
'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'à'=>'a', 'á'=>'a',
'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'ae',
'ç'=>'c', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e',
'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ñ'=>'n',
'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o',
'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ü'=>'u',
'ý'=>'y', 'ÿ'=>'y' }
s.encode('ASCII',fallback: lambda { |c| fallback.key?(c) ? fallback[c] : undefined })
end
但它只是给了我以下字符串:
J'ai t mise au courant des ventualits temps。
甚至:
J'ai t' mise au courant des 'ventualit's temps。
我不明白为什么它不起作用...
编辑:
我正在使用
file = File.open(i_FileName, 'r:utf-8')
要读取文件,我将其替换为
file = File.open(i_FileName, 'r:iso-8859-1:utf-8')
它就像一个魅力!
解决方案
TL;DR:使用String#unicode_normalize
.
é
可能是 1 个符号(所谓的 Unicode 组合形式)以及 2(两个)不同的符号(Unicode 分解形式)引发了意想不到的结果。
"J'ai été mise au courant des éventualités à temps.".
unicode_normalize(:nfd).
gsub(/./) { |m| m.ord > 255 ? '' : m }
#⇒ "J'ai ete mise au courant des eventualites a temps."
或者,甚至更简单:
"J'ai été mise au courant des éventualités à temps.".
unicode_normalize(:nfd).gsub(/[\u0300-\u036F]/, '')
#⇒ "J'ai ete mise au courant des eventualites a temps."
我们在这里所做的是:我们将字符串规范化为分解形式(所有组合的变音符号成为单独的符号。)然后我们用String#gsub
.
如果您觉得丢掉现有代码感到遗憾,请将字符串规范化为组合形式并使用您的encode
,现在它可以工作了。
composed = "J'ai été mise au courant des éventualités à temps.".
unicode_normalize(:nfc) # NOTE :nfc parameter
composed.encode(.....)
推荐阅读
- php - PhpStorm Xdebug 框架和变量不可用
- pandas - Pandas group by moth only returns January
- python - 有效地选择每个项目有可能被挑选的子集
- c++ - 无法编译简单的 C++17 程序
- c# - 我可以使用带有事件处理程序的按钮将用户发送到不同的 xaml 屏幕吗?
- manjaro - Luks 内容不可见/不可访问 - Manjaro Linux
- python - 带有芹菜执行器的气流用于内存饥饿的 Dags
- node.js - 为什么我每次在ubuntu都要写sudo
- sql - 如何在 SQL Server 中将主表选定列值作为子查询列名传递
- c++ - 是否可以在堆中分配向量但通过引用访问?