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


80

我正在使用此代码:

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] 
}

Answers:


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

map应该如何理解它的语义?我了解,collect但是我总是很难理解地图。
OscarRyz

3
@Oscar Reyes,Enumerable#map是Enumerable#collect的同义词
Wayne Conrad

3
仅供参考:如果您将数字除以其他字符,则只会获取数字的第一个“大块”。因此,对于“ 123ABC456”,它只会抓取“ 123”。如果要获取所有数字,请使用line.gsub(/ [^ 0-9] /,'')之类的东西。
约书亚·品特

4
还应该阐明这适用于枚举,例如数组,而不是标题要求的字符串
allenwlee 2015年

4
NoMethodError:字符串的未定义方法“ map”
Garry Gomez


62

还有更简单的解决方案

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

这仅返回字符串中连续数字的第一个匹配项。所以'ab123cd45'.scan(/\d+/).first就回来了12
lacostenycoder

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

这应该工作。


请考虑编辑您的文章,以添加更多有关代码功能以及其解决问题原因的解释。通常只包含代码(即使它在起作用)的答案通常不会帮助OP理解他们的问题。
SuperBiasedMan

4

最简单,最快的方法是从字符串中获取所有整数。

str = 'abc123def456'

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

将长字符串中的基准与此处提供的其他一些解决方案进行比较,我们可以看到这快了几个数量级:

require 'benchmark'

@string = [*'a'..'z'].concat([*1..10_000].map(&:to_s)).shuffle.join

Benchmark.bm(10) do |x|
  x.report(:each_char) do
    @string.each_char{ |c| @string.delete!(c) if c.ord<48 or c.ord>57 }
  end
  x.report(:match) do |x|
    /\d+/.match(@string).to_s
  end
  x.report(:map) do |x|
    @string.split.map {|x| x[/\d+/]}
  end
  x.report(:gsub) do |x|
    @string.gsub(/\D/, '')
  end
  x.report(:delete) do
    @string.delete("^0-9")
  end
end

             user     system      total        real
each_char    0.020000   0.020000   0.040000 (  0.037325)
match        0.000000   0.000000   0.000000 (  0.001379)
map          0.000000   0.000000   0.000000 (  0.001414)
gsub         0.000000   0.000000   0.000000 (  0.000582)
delete       0.000000   0.000000   0.000000 (  0.000060)

2

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

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

这应该返回一个


通常,在多字节字符集时代,像这样的常规用法作为通用解决方案会有些危险。根据要处理的字符和字符集,在不同的语言环境中事情可能会得到不同的结果。
布伦登·怀特利

0

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

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

它应该返回 1234


您不需要matchtry是否使用此字符串匹配语法str[/\d+/]
lacostenycoder

也不.try是核心的红宝石,所以这个答案在没有active_support/core_ext/object/try.rb或失败的情况下会失败
lacostenycoder
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.