我的字符串包含员工徽章编号(从1000开始)和10分以下的分数:
'9999 got a score of 7'
'9999 7'
'7 9999'
'employee 9999 was very good and I give them a score of 7'
我可以提取徽章编号:
my_string.split.find do |badge_number|
Employee.exists?(badge_number: badge_number.to_i)
end
如何从10中提取分数?
答案 0 :(得分:4)
鉴于您使用的字符串始终具有相同的格式,我将使用String#scan
方法:
string = '9999 got a score of 7'
badge_number, score = string.scan(/\d+/)
badge_number
# => "9999"
score
# => "7"
答案 1 :(得分:1)
如果字符串格式永远不会改变而你总是想要最后一个数字,我会使用一个非常简单的模式:
my_string = '9999 got a score of 7'
my_string[/(\d+)$/, 1] # => "7"
将其转换为整数:
my_string[/(\d+)$/, 1].to_i # => 7
如果您想同时使用这两个号码,请使用@ {toro2K推荐的scan
。
关于您的代码:
my_string = '9999 got a score of 7'
my_string.split.find do |badge_number|
Employee.exists?(badge_number: badge_number.to_i)
end
唉。不要那样做。以下是你要求Ruby做的事情:
my_string = '9999 got a score of 7'
my_string.split # => ["9999", "got", "a", "score", "of", "7"]
将这些值转换为整数会导致:
my_string.split.map(&:to_i) # => [9999, 0, 0, 0, 0, 7]
因此,对于您split
字符串时找到的每个单词,您都要求Ruby在您的数据库或容器中搜索徽章编号。 <幸运(与设计相反),您想要的第一个是徽章编号,由to_i
返回,允许find
满足并通过。如果您的字符串格式不同,那么您将打败您的数据库或代码。如果字符串更改格式,并且分数是第一个,或者您的徽章为#0,则您的代码将返回错误结果。
最后,您可能需要重新考虑使用徽章编号的整数字段。你打算对数值做数学吗?如果没有,为什么强制你的代码转换为整数?是否可以想象徽章编号实际上可以以零(0
)开头?使用整数字段将导致修剪前导零。我建议改用字符串值。
答案 2 :(得分:0)
您可以使用正则表达式:
result = my_string.match(/(\d+) got a score of (\d+)/)
然后,您可以使用result[1]
和result[2]
获取徽章编号和分数。
正则表达式的(\d+)
部分至少匹配一个数字。
答案 3 :(得分:0)
你使用的是这个错误。 split
将返回一个数组。使用find
将其转换为枚举器,然后搜索数组中的每个元素(字符串中的每个单词和数字)。
你能做什么:
badge_number = my_string.split.first.to_i
score = my_string.split.last.to_i
然后使用那些变量。 (这假设字符串总是在同一个地方有这个信息)
答案 4 :(得分:0)
如果
=~
与带有命名捕获的正则表达式文字一起使用,则捕获的字符串(或nil)将分配给由捕获名称命名的局部变量。
my_string = '9999 got a score of 7'
/(?<bagde_number>\d+)\D+(?<score>\d+)/ =~ my_string
bagde_number # => "9999"
score # => "7"