如何在Rails 2.0/Ruby 1.8.6中查找字符串数组中的非ASCII字符串?

4

我有一个从数据库中加载的用户登录名数组。如何最简单和高效地保留只包含非ASCII字符的登录名?

logins = Users.find(:all).map{|user|user.login}
logins_with_non_ascii_characters = logins.select{ |login| ...??? }

谢谢

编辑: 如果您有一个SQL解决方案(我使用MySQL,但通用解决方案更好),可以通过:conditions子句直接过滤第一行的登录信息,那么我也可以接受。实际上,这样会更有效率:

logins = Users.find(:all, :conditions => "...???").map{|user|user.login}
3个回答

9
你可以滥用Ruby内置的正则表达式字符类来实现这一点。
[:print:]包含所有ASCII可打印字符。 它不包含ASCII字符,例如beeps或者重要的多字节字符。
在假设你的用户不太可能将ASCII BEEP作为密码中的字符的情况下进行操作。
#reject if has non-ascii character
valid_users = users.reject! {|user| user.login =~ /[^[:print:]]/} 

应该能够为您完成此操作。

顺便提一下,您可以通过以下方式生成可打印的ASCII字符列表:(32..127).map(&:chr).join - New Alexandria

2
我目前找到的只有这个:

到目前为止,我找到的只有这个:

def is_ascii(str)
    str.each_byte {|c| return false if c>=128}
    true
end

logins = Users.find(:all).map{|user|user.login}
logins_with_non_ascii_characters = logins.select{ |login| not is_ascii(login) }

这有点令人失望,而且显然不够高效。有没有更好的想法?


1
需要高效吗?听起来这好像只是一次操作。 - John Topley
@约翰:说得好,它不一定非得高效。我只是更喜欢高效的解决方案,而且我相信这会有助于我更好地理解 Ruby。但在这种情况下,这个解决方案也可以正常工作。 - MiniQuark

1
您可以从用户中仅选择登录列:
non_ascii = /[\u0080-\uffff]/
logins = Users.select(:login).find_all {|login| login =~ non_ascii }

或者在 Ruby 2.0 中使用 /\p{ASCII}/


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