从一个Ruby字符串中删除除字母和数字以外的所有字符。

30

我在表单中有一个字符串输入字段。我通过params哈希获取该值。如何从该字符串中删除除字母和数字以外的所有字符。

请注意,以下是翻译文本,其中包括HTML标记:

我在表单中有一个字符串输入字段。我通过params哈希获取该值。如何从该字符串中删除除字母和数字以外的所有字符。


3
为了帮助您的学习过程:http://www.rubular.com/ - apneadiving
3个回答

64

只是提醒人们好的老朋友 tr

asdf.tr('^A-Za-z0-9', '')

这是通过查找字符范围的补集并将字符转换为空字符串来实现的。

我想知道使用\W字符类是否比使用字符范围、gsubtr更快:

require 'benchmark'

asdf = [('A'..'z').to_a, ('0'..'9').to_a].join

puts asdf
puts asdf.tr(   '^A-Za-z0-9',    '' )
puts asdf.gsub( /[\W_]+/,        '' )
puts asdf.gsub( /\W+/,           '' )
puts asdf.gsub( /\W/,            '' )
puts asdf.gsub( /[^A-Za-z0-9]+/, '' )
puts asdf.scan(/[a-z\d]/i).join

n = 100_000
Benchmark.bm(7) do |x|
  x.report("tr:")    { n.times do; asdf.tr('^A-Za-z0-9', '');      end }
  x.report("gsub1:") { n.times do; asdf.gsub(/[\W_]+/, '');        end }
  x.report("gsub2:") { n.times do; asdf.gsub(/\W+/, '');           end }
  x.report("gsub3:") { n.times do; asdf.gsub(/\W/, '');            end }
  x.report("gsub4:") { n.times do; asdf.gsub(/[^A-Za-z0-9]+/, ''); end }
  x.report("scan:")  { n.times do; asdf.scan(/[a-z\d]/i).join;     end }
end

>> ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz0123456789
>> ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
>> ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
>> ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789
>> ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789
>> ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
>> ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
>>              user     system      total        real
>> tr:      0.560000   0.000000   0.560000 (  0.557883)
>> gsub1:   0.510000   0.000000   0.510000 (  0.513244)
>> gsub2:   0.820000   0.000000   0.820000 (  0.823816)
>> gsub3:   0.960000   0.000000   0.960000 (  0.955848)
>> gsub4:   0.900000   0.000000   0.900000 (  0.902166)
>> scan:    5.630000   0.010000   5.640000 (  5.630990)

你可以看到有几个模式没有匹配下划线'_', 这是'\w'的一部分,因此未满足 OP 的要求。


你尝试过不加“+”使用asdf.gsub( /[\W_]/, '' )吗?有区别吗? - rafaelkin
我没有,但你可以。将代码复制到您自己的系统中并尝试它。 - the Tin Man

21

不使用正则表达式:

garbage = 'ab_c<>?AB C!@#123'
puts garbage.delete("^a-zA-Z0-9") #=> abcABC123

'^'符号之后的所有内容都将被否定。


7
=> '^/how/now#(Brown) Cow'.gsub /\W/, '' # or /[\W_]/
=> "hownowBrownCow"

根据评论更新...


2
或者你可以直接使用.gsub /\W/, '',因为\W匹配任何非单词字符(而\w匹配单词字符)。 - Michael Kohl
或者你可以直接使用.gsub /\W/, '',因为\W匹配任何非单词字符(而\w匹配单词字符)。接近了,但还不够。\w匹配[A-Za-z0-9_]('Z'..'a').to_a.join.gsub(/\W+/, '') #=> "Z_a" - the Tin Man
我猜道德是“检查此答案的编辑历史记录”并进行测试。 :-) - DigitalRoss
@the Tin Man:大多数Ruby正则表达式教程将“单词字符”定义为“\w 单词字符 [0-9A-Za-z_]”。 - Michael Kohl
OP 请求删除除字母和数字以外的所有内容。\W 会允许 '_' 保留。[\W_] 将捕获 '_' 并强制将其删除,从而仅保留字母和数字字符。您可以在我创建的基准输出中看到这一点。 - the Tin Man
显示剩余2条评论

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