REPLACEMENTS = {
'á' => "a",
'ë' => 'e',
}
encoding_options = {
:invalid => :replace, # Replace invalid byte sequences
:replace => "", # Use a blank for those replacements
:universal_newline => true, # Always break lines with \n
# For any character that isn't defined in ASCII, run this
# code to find out how to replace it
:fallback => lambda { |char|
# If no replacement is specified, use an empty string
REPLACEMENTS.fetch(char, "")
},
}
ascii = non_ascii_string.encode(Encoding.find('ASCII'), encoding_options)
puts ascii.inspect
#=> "abcaee123ABC"
更新
有些人报告了:universal_newline选项的问题。我断断续续地看到了这一点,但一直无法追查原因。 当它发生时,我看到了Encoding::ConverterNotFoundError: code converter not found (universal_newline)。然而,在一些RVM更新之后,我只是在以下Ruby版本下运行了上面的脚本,没有任何问题:
class String
def remove_nonascii(replacement)
n=self.split("")
self.slice!(0..self.size)
n.each { |b|
if b[0].to_i< 33 || b[0].to_i>127 then
self.concat(replacement)
else
self.concat(b)
end
}
self.to_s
end
end
9条答案
按热度按时间q0qdq0h21#
使用字符串#encode
从Ruby 1.9开始,在字符串编码之间进行转换的官方方式是使用字符串#encode。
要简单地删除非ASCII字符,可以执行以下操作:
请注意,结果中的前5个字符是“abce1”--丢弃了“á”,丢弃了一个“ë”,但另一个“ë”似乎已转换为“e”。
这样做的原因是有时有多种方式来用Unicode来表达相同的书写字符。“á”是一个单一的Unicode码点。第一个“ë”也是如此。当Ruby在转换过程中看到它们时,它会丢弃它们。
但第二个“ë”是两个代码点:一个普通的“e”,就像您在ASCII字符串中看到的一样,后面跟着一个“组合变音符号”(this one),意思是“在前一个字符上加一个变音符号”。在Unicode字符串中,这些字符被解释为单个“字素”或可见字符。在转换时,Ruby保留普通的ASCII“e”,并丢弃组合标记。
如果您决定要提供一些特定的替换值,您可以这样做:
更新
有些人报告了
:universal_newline
选项的问题。我断断续续地看到了这一点,但一直无法追查原因。当它发生时,我看到了
Encoding::ConverterNotFoundError: code converter not found (universal_newline)
。然而,在一些RVM更新之后,我只是在以下Ruby版本下运行了上面的脚本,没有任何问题:鉴于此,它似乎不是Ruby中的一个弃用功能,甚至也不是一个错误。如果有人知道原因,请发表评论。
a6b3iqyw2#
c7rzv4ha3#
以下是我使用Iconv的建议。
xqk2d5yq4#
如果您有积极的支持,您可以使用I18n.音译
或者如果你不想要问号..。
请注意,这不会删除无效的字节序列,而只是替换非ASCII字符。对于我的用例,这就是我想要的,而且很简单。
j2cgzkjk5#
在@masakielact的帮助下,我使用#chars方法解决了这个问题。
诀窍是将每个字符分解成**它自己的单独块*,这样Ruby就可以失败*。
当Ruby遇到二进制代码等问题时,它需要失败。如果你不允许Ruby继续前进并失败,那么当涉及到这些事情时,这是一条艰难的道路。因此,我使用字符串#chars方法将给定的字符串分解为一个字符数组。然后,我将该代码传递到一个清理方法中,该方法允许代码在字符串中具有“微故障”(我的新词)。
因此,给定一个“脏”字符串,假设您在图片上使用了
File#read
。(我的案例)wz3gfoph6#
57hvy0tb7#
Quick GS揭示了this discussion,这表明了以下方法:
xriantvc8#
不,除了基本字符之外,并不缺少删除所有字符(这是上面推荐的)。最好的解决方案是正确地处理这些名称(因为现在大多数文件系统在Unicode名称方面没有任何问题)。如果你的用户粘贴了连字,他们肯定会想要把它们也拿回来。如果文件系统是您的问题,请将其抽象出来,并将文件名设置为某个MD5(这也允许您轻松地将上传内容碎片到存储桶中,这些存储桶扫描速度非常快,因为它们从来不会有太多条目)。
gg0vcinb9#
这应该会起到作用: