如何去除ruby中的非ascii字符

如何去除ruby中的非ascii字符,ruby,unicode,cgi,ascii,Ruby,Unicode,Cgi,Ascii,我有一个Ruby CGI(不是rails),它从web表单中选择照片和标题。我的用户非常喜欢使用智能引号和连字,他们从其他来源粘贴。我的web应用程序不能很好地处理这些非ASCII字符,是否有一个快速Ruby字符串操作例程可以去除非ASCII字符?quick GS建议使用以下方法: class String def remove_nonascii(replacement) n=self.split("") self.slice!(0..self.size) n.eac

我有一个Ruby CGI(不是rails),它从web表单中选择照片和标题。我的用户非常喜欢使用智能引号和连字,他们从其他来源粘贴。我的web应用程序不能很好地处理这些非ASCII字符,是否有一个快速Ruby字符串操作例程可以去除非ASCII字符?

quick GS建议使用以下方法:

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
类字符串
def拆卸_nonascii(更换)
n=自拆分(“”)
自我剖析!(0.自身尺寸)
n、 每个{124; b|
如果b[0]。to|i<33 | b[0]。to|i>127,则
自我保护(更换)
其他的
自我控制(b)
结束
}
自我介绍
结束
结束

不,除了基本字符(上面建议使用)之外,还需要删除所有字符。最好的解决方法是正确处理这些名称(因为现在大多数文件系统都没有Unicode名称的问题)。如果你的用户粘贴了连字,他们肯定也会想要拿回它们。如果文件系统是您的问题,请将其抽象出来,并将文件名设置为md5(这也允许您轻松地将文件分片上传到bucket中,这样可以非常快速地进行扫描,因为它们从来没有过多的条目)。

下面是我使用Iconv的建议

class String
  def remove_non_ascii
    require 'iconv'
    Iconv.conv('ASCII//IGNORE', 'UTF8', self)
  end
end
使用字符串#编码 从Ruby 1.9开始,在字符串编码之间转换的官方方法是使用

要简单地删除非ASCII字符,可以执行以下操作:

some_ascii   = "abc"
some_unicode = "áëëçüñżλφθΩWith a bit of help from @masakielastic I have solved this problem for my personal purposes using the #chars method.

The trick is to break down each character into its own separate block so that ruby can fail.

Ruby needs to fail when it confronts binary code etc. If you don't allow ruby to go ahead and fail its a tough road when it comes to this stuff. So I use the String#chars method to break the given string into an array of characters. Then I pass that code into a sanitizing method that allows the code to have "microfailures" (my coinage) within the string.

So, given a "dirty" string, lets say you used
File#read
on a picture. (my case)

dirty = File.open(filepath).read    
clean_chars = dirty.chars.select do |c|
  begin
    num_or_letter?(c)
  rescue ArgumentError
    next
  end
end
clean = clean_chars.join("")

def num_or_letter?(char)
  if char =~ /[a-zA-Z0-9]/
    true
  elsif char =~ Regexp.union(" ", ".", "?", "-", "+", "/", ",", "(", ")")
    true
  end
end
some_ascii=“abc”

在@masakelastic的一些帮助下,我使用#chars方法出于个人目的解决了这个问题

诀窍是将每个字符分解为它自己的独立块,这样ruby就可能失败

Ruby在遇到二进制代码等问题时需要失败。如果你不允许Ruby继续前进并失败,那么在这个问题上,这是一条艰难的道路。因此,我使用String#chars方法将给定的字符串分解为一个字符数组。然后我将该代码传递到一个清理方法中,该方法允许代码出现“微故障”(我的发明)在字符串内

因此,给定一个“脏”字符串,假设您在图片上使用了
File#read
。(我的案例)

类字符串
def条带控制字符
self.chars.reject{char | char.ascii_only?and(char.ord<32或char.ord==127)}.join
结束
结束

如果您有积极的支持,您可以使用I18n.translitate


I18n.音译(“áëeççñżλφθΩ是的,我发现它不处理unicode双字节字符,对吗?好吧,我会测试这个,谢谢你的帮助!这是创建ASCII投影删除unicode字符的最简单方法。它不会创建干净的转换,并且为单个多字节unicode字符注入多个替换字符。不过,这是适合我工作的工具。在ruby 1.9中,我遇到了一个异常“无效的多字节转义”。为了修复它,我使用了\u0080-\u00ff,而不是\x80-\xff…但是,您需要删除ruby build p194(1.9.3-p194)中的universal\u换行选项。最后,谢谢您!(但对我来说,它只是在否定之后才起作用/[^\u0080-\u00ff]/)这是一个非常糟糕的解决方案。存在0x10FF7F非ASCII字符。这将适用于其中的0.01%,并且不包括OP提到的字符。如果要使用gsub,则Regexp应该是
/[^\x00-\x7F]/
。这看起来是从Unicode转换为ASCII的合法方式。我发现找不到代码转换器(universal\u newline)对于ruby-1.9.3-P429,将符号
:universal\u newline
更改为
:universal\u newline\u DECORATOR
为我解决了这个问题。这对我帮助很大,这是唯一对我有效的方法!谢谢Nathan!在ruby 2.5.0上,我在尝试从文本中删除Unicode字符时遇到了一个编码::UnknownConversionError。我通过在Ruby 2.7的编码选项hashUpdate中添加
:undef=>:replace,
来修复这个问题。添加双splat来修复最后一个参数弃用警告。
encode(Encoding.find('ASCII'),**Encoding_options)
some_ascii   = "abc"
some_unicode = "áëëçüñżλφθΩWith a bit of help from @masakielastic I have solved this problem for my personal purposes using the #chars method.

The trick is to break down each character into its own separate block so that ruby can fail.

Ruby needs to fail when it confronts binary code etc. If you don't allow ruby to go ahead and fail its a tough road when it comes to this stuff. So I use the String#chars method to break the given string into an array of characters. Then I pass that code into a sanitizing method that allows the code to have "microfailures" (my coinage) within the string.

So, given a "dirty" string, lets say you used
File#read
on a picture. (my case)

dirty = File.open(filepath).read    
clean_chars = dirty.chars.select do |c|
  begin
    num_or_letter?(c)
  rescue ArgumentError
    next
  end
end
clean = clean_chars.join("")

def num_or_letter?(char)
  if char =~ /[a-zA-Z0-9]/
    true
  elsif char =~ Regexp.union(" ", ".", "?", "-", "+", "/", ",", "(", ")")
    true
  end
end