【问题标题】:Remove all characters except alphabets and numbers from a Ruby string从 Ruby 字符串中删除除字母和数字之外的所有字符
【发布时间】:2011-01-10 19:47:41
【问题描述】:

我在表单中有一个字符串输入字段。我在 params hash 中得到这个值。我应该如何从该字符串中删除除字母和数字之外的所有字符。

【问题讨论】:

标签: ruby string


【解决方案1】:

只是为了提醒人们好'ol 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_]/, '' )?有区别吗?
  • 我没有,但你可以。把代码复制到自己的系统上试试看。
【解决方案2】:

没有正则表达式:

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

其中 '^' 否定它之后的所有内容。

【讨论】:

    【解决方案3】:
    => '^/how/now#(Brown) Cow'.gsub /\W/, '' # or /[\W_]/
    => "hownowBrownCow"
    

    ...根据 cmets 更新...

    【讨论】:

    • 或者你可以只使用.gsub /\W/, '',因为\W 匹配任何非单词字符(而\w 匹配单词字符)。
    • "或者您可以只使用 .gsub /\W/, '',因为 \W 匹配任何非单词字符(而 \w 匹配单词字符)"。关闭,但不完全。 \w 匹配 [A-Za-z0-9_]('Z'..'a').to_a.join.gsub(/\W+/, '') #=&gt; "Z_a"
    • 我猜道德是“检查这个答案的编辑历史”并进行测试。 :-)
    • @the Tin Man:大多数 Ruby 正则表达式如何定义“单词字符”,如“\w 单词字符 [0-9A-Za-z_]”。
    • 是一样的。范围的顺序并不重要,重要的是包含范围;换句话说,“a-z”在“A-Z”还是“0-9”之前都没有关系。重要的是他们在某个地方。
    猜你喜欢
    • 2010-10-24
    • 2017-09-01
    • 1970-01-01
    • 2011-11-08
    • 2022-01-09
    • 1970-01-01
    • 2011-06-23
    • 2017-04-05
    • 2014-06-02
    相关资源
    最近更新 更多