将UTF-8字符转换为正确的ASCII字符

3
我有一个字符串"V\355ctor"(我认为应该是Víctor)。是否有一种方法将其转换为ASCII,其中í将被替换为ASCII i
我已经尝试了Iconv,但没有成功。(我只得到了Iconv::IllegalSequence: "\355ctor"
此外,Ruby 1.8.7和Ruby 2.0之间有什么区别吗?
编辑:Iconv.iconv('UTF-8//IGNORE', 'UTF-8', "V\355ctor")似乎可以工作,但结果是Vctor而不是Victor

你需要做多少工作?你只是想去掉重音,还是也想将土耳其的 ı 转换为简单的 i - mu is too short
只需要用一个简单的 i 替换它,我不想“忽略”这个字符。 - Benedikt B
3
你的输入不是 UTF-8,很可能是 ISO-8859-1。虽然这不是你需要的答案,但如果你从错误的假设开始关于输入字符串的编码方式,就无法得到合理的转换。为了获得正确的 ASCII 翻译,必须正确设置编码方式。 - Neil Slater
就像@NeilSlater所说的那样。 值为八进制355 / 十进制237的字节后跟一个“c”在UTF-8中是不合法的,其中“í”字符编码为两个字节:八进制303 / 十进制195后跟八进制255 / 十进制173。 - Mark Reed
谢谢Neil和Mark,但是像Iconv.iconv("ISO-8859-1", "ASCII", "V\355ctor")这样的东西对我来说会引发Iconv::IllegalSequence错误(我已经尝试了很多组合)。 - Benedikt B
2个回答

8
我知道两种选择。
  1. transliterate from the I18n gem.

    $ irb
    1.9.3-p448 :001 > string = "Víctor"
     => "Víctor" 
    1.9.3-p448 :002 > require 'i18n'
     => true 
    1.9.3-p448 :003 > I18n.transliterate(string)
     => "Victor"
    
  2. Unidecoder from the stringex gem.

    Stringex::Unidecoder..decode(string)
    

更新:

在运行Unidecoder时,输入“V\355ctor”,会出现以下错误:

Encoding::CompatibilityError: incompatible encoding regexp match (UTF-8 regexp with IBM437 string)

嗯,也许你想先从IBM437转换:

string.force_encoding('IBM437').encode('UTF-8')

这可能会帮助您进一步了解。请注意,自动检测的编码可能不正确,如果您确切知道编码是什么,那么这将使一切变得更加容易。

看起来Víctor应该是V\303\255ctor,而不是V\355ctor?您的例子可行,但对于我来说,V\355ctor返回V?or - Benedikt B

4
你想做的事情叫做音译
最常用且维护最好的库是ICU。(Iconv也经常被使用,但它有许多限制,比如你遇到的那个。)
简单的谷歌搜索会得到一些 Ruby ICU 封装器。恐怕我无法评论哪一个更好,因为我承认从未使用过它们。但这是你想要使用的东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接