在Ruby中从字符串中提取数字

yiytaume  于 12个月前  发布在  Ruby
关注(0)|答案(8)|浏览(97)

我使用这个代码:

s = line.match( /ABCD(\d{4})/ ).values_at( 1 )[0]

从字符串中提取数字,如:

ABCD1234
ABCD1235
ABCD1236


它可以工作,但我想知道在Ruby中还有什么其他的选择?
我的代码:

ids = [] 
someBigString.lines.each {|line|
   ids << line.match( /ABCD(\d{4})/ ).values_at( 1 )[0] 
}
kxxlusnw

kxxlusnw1#

根据http://www.ruby-forum.com/topic/125709,有许多Ruby方法

  1. line.scan(/\d/).join('')
  2. line.gsub(/[^0-9]/, '')
  3. line.gsub(/[^\d]/, '')
  4. line.tr("^0-9", '')
  5. line.delete("^0-9")
  6. line.split(/[^\d]/).join
  7. line.gsub(/\D/, '')
    在您的控制台上尝试每个。
    还可以查看该帖子中的基准报告。
b1uwtaje

b1uwtaje2#

还有更简单的解决办法

line.scan(/\d+/).first
xeufq47z

xeufq47z3#

a.map {|x| x[/\d+/]}
gstyhher

gstyhher4#

最简单和最快的方法是使用正则表达式从字符串中解析出整数。

str = 'abc123def456' 

str.delete("^0-9")
=> "123456"

str.tr("^0-9","")
=> "123456"

将长字符串上的基准测试与本文提供的其他一些解决方案进行比较,我们可以看到tr最快,delete接近第二。

require 'benchmark'

n = 2 
string = [*'a'..'z'].concat([*1..1_000_000].map(&:to_s)).shuffle.join

Benchmark.bmbm do |x|
  x.report('scan') do
    n.times {string.scan(/\d/).join}
  end
  x.report('gsub') do
    n.times {string.gsub(/[^\d]/,"")}
  end
  x.report('gsub2') do
    n.times {string.gsub(/\D/, '')}
  end
  x.report('tr') do
    n.times {string.tr("^0-9","")}
  end
  x.report('delete') do
    n.times {string.delete('^0-9')}
  end
  x.report('split') do
    n.times {string.split(/[^\d]/).join}
  end
end

Rehearsal ------------------------------------------
scan     3.509973   0.187274   3.697247 (  3.717773)
gsub     0.229568   0.002790   0.232358 (  0.233961)
gsub2    0.307728   0.013435   0.321163 (  0.390262)
tr       0.021395   0.000223   0.021618 (  0.022297)
delete   0.021290   0.002280   0.023570 (  0.024365)
split    0.284935   0.010274   0.295209 (  0.299865)
--------------------------------- total: 4.591165sec

             user     system      total        real
scan     3.146615   0.126009   3.272624 (  3.281860)
gsub     0.211263   0.001515   0.212778 (  0.213170)
gsub2    0.208482   0.000424   0.208906 (  0.209339)
tr       0.015228   0.000086   0.015314 (  0.015387)
delete   0.015786   0.000128   0.015914 (  0.016050)
split    0.205096   0.002736   0.207832 (  0.208380)
lztngnrs

lztngnrs5#

your_input = "abc1cd2"
your_input.split(//).map {|x| x[/\d+/]}.compact.join("").to_i

这个应该能用

gdrx4gfi

gdrx4gfi6#

另一个解决方案可能是这样写:

myString = "sami103"
myString.each_char{ |c| myString.delete!(c) if c.ord<48 or c.ord>57 } #In this case, we are deleting all characters that do not represent numbers.

如果你输入

myNumber = myString.to_i #or myString.to_f

这应该返回一个

8ulbf1ek

8ulbf1ek7#

数字串可以是小数和/或负数。因此:

[string.chr == "-" ? "-" : nil, string.delete("^.0-9")].compact.inject(:+)

这利用chr方法来检查字符串是否以负号-开头。然后它剥离除了数字和小数之外的所有内容,然后如果-最初在那里,则将其前置。
这允许与to_ito_f方法链接。

  • compact从数组中删除nil,如果它不是负数
  • inject(:+)根据数组内容的顺序将数组重新转换为字符串
q35jwt9p

q35jwt9p8#

要从字符串中提取数字部分,请使用以下命令:

str = 'abcd1234'
/\d+/.match(str).try(:[], 0)

返回1234

相关问题