正则表达式 - 字符串中的第一个整数(跳过浮点数)

时间:2013-12-17 04:14:13

标签: ruby regex

**更新

现在我正在做

a = gets

count = ((a.match(/\d+/)).to_s).to_i. 

样本输入:2000 of 3.00

实际输出:2000

样本输入:2000年的3.00

实际输出:3

目标输出:两种情况下均为2000(跳过浮动)

7 个答案:

答案 0 :(得分:1)

"3.00 of 2000"[/(?<![.\d])\d+(?![.\d])/].to_i    # => 2000
"2000 of 3.00"[/(?<![.\d])\d+(?![.\d])/].to_i    # => 2000

答案 1 :(得分:0)

这是您必须知道数据的情况之一。如果您知道输入将始终只有一个整数,那么以下方法将起作用:

'3.00 of 2000'.split.select { |e| e =~ /^\d+$/ }.last.to_i
#=> 2000

'2000 of 3.00'.split.select { |e| e =~ /^\d+$/ }.last.to_i
#=> 2000

这个想法是将每行输入分成一个数组,然后只选择除数字之外什么都不包含的数组元素。最后,数组的最后一个(希望是唯一的)元素被转换为整数。

在任意输入下,有很多方法可能会爆炸或无法达到您想要的结果。但是,它肯定适用于您提供的特定语料库。

答案 2 :(得分:0)

使用代码:

a = gets

a.split(/[\sa-z]+/).select {| v | v !~ /\./ }.last.to_i

# => 2000

答案 3 :(得分:0)

没有正则表达式但是......

'2000 to 3.00'.split.find { |s| s.to_i.to_s == s }.to_i
 => 2000 
'3.00 to 2000'.split.find { |s| s.to_i.to_s == s }.to_i
 => 2000 

答案 4 :(得分:0)

str = '3 of 20.00, +42,31 of 455, -6 of -23.7 .'
str.scan(/(?<![\.\d])(-?\d+)(?!\d*\.)/).flatten.map(&:to_i)
  => [3, 42, 31, 455, -6] 
  • 捕获组(-?\d+)由一个或多个数字0-9组成,可选地前面带有减号。
  • (?<![\.\d])是一个负向的后视组,意味着捕获组前面不能有小数点或数字。
  • (?!\d*\.)/)是一个负向前瞻组,这意味着捕获组后面不能跟零个或多个数字后跟一个小数点。
  • str.scan(/(?<![\.\d])(-?\d+)(?!\d*\.)/) #=> [["3"], ["42"], ["31"], ["455"], ["-6"]],这就是为什么在转换为整数之前必须应用flatten
  • 最初我尝试(?<!\.\d*)作为负面的后视组,但这会产生错误。原因是:消极的外观不可变长。我理解同样的限制适用于Perl。
编辑:我忽略了问题的标题。要仅检索第一个整数,请在.first末尾添加str.scan或用以下内容替换该语句:

str.match(/(?<![\.\d])(-?\d+)(?!\d*\.)/)[0].to_i

答案 5 :(得分:0)

正则表达式[^0-9.]([0-9]+)[^0-9]将仅匹配与非数字或点的字符相邻的数字,并捕获单个捕获组中的数字。

如果数字也可以出现在字符串的开头或结尾附近,则修复应该是不言而喻的;

(?:^|[^0-9.])([0-9]+)(?:[^0-9.]|$)

答案 6 :(得分:0)

words_containing_non_digits = -> x {x[/\D/]}
p '3.00 of 2000'.split.reject &words_containing_non_digits #=> ["2000"]