Regex-字符串中的第一个整数(跳过浮点)



**更新

现在我在做

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

样本输入:3.00 的2000

实际产量:2000

样本输入:2000 中的3.00

实际输出:3

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

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

这是您必须了解数据的情况之一。如果你知道你的输入总是只有一个整数,那么下面的方法会起作用:

'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

其想法是将每一行输入拆分为一个数组,然后只选择只包含数字的数组元素。最后,数组的最后一个(希望也是唯一一个)元素被转换为整数。

在给定任意输入的情况下,有很多方法可能会失败或无法实现您想要的结果。然而,它确实适用于您提供的特定语料库。

使用代码:

a = gets
a.split(/[sa-z]+/).select {| v | v !~ /./ }.last.to_i
# => 2000

没有正则表达式,但。。。

'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 

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

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

(?:^|[^0-9.])([0-9]+)(?:[^0-9.]|$)
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组成,可选地在数字0-9前面加一个减号
  • (?<![.d])是一个负查找组,这意味着捕获组前面不能有小数点或数字
  • (?!d*.)/)是一个负前瞻组,这意味着捕获组后面不能跟零个或多个数字,后面跟一个小数点
  • str.scan(/(?<![.d])(-?d+)(?!d*.)/) #=> [["3"], ["42"], ["31"], ["455"], ["-6"]],这就是为什么在转换为整数之前必须应用flatten
  • 最初,我尝试将(?<!.d*)作为负后备组,但这产生了一个错误。原因是:负lookbehinds不能是可变长度的。我知道Perl中也有同样的限制

编辑:我不知怎么忽略了问题的标题。要只检索第一个整数,请在str.scan的末尾加上.first,或者将该语句替换为:

str.match(/(?<![.d])(-?d+)(?!d*.)/)[0].to_i
words_containing_non_digits = -> x {x[/D/]}
p '3.00 of 2000'.split.reject &words_containing_non_digits #=> ["2000"]

最新更新