Ruby-切割字符串中下划线前的所有字符

3
我有一个字符串,如 solution_10,我想从中删除部分 solution_,下划线后面的数字将增加,可能是 1001000 甚至更大。我似乎无法想到如何做到这一点。
我尝试使用 slice!(0, 9),但这会给我 solution_,然后我尝试了 slice!(0, -2),但这会给我 null,
我接着尝试使用 solution_10[1..9],这给我 ortable_1 所以我的问题是如何摆脱所有字符直到下划线,我只想要下划线后面的数字。

1
你可以尝试使用 "solution_10"[/\d+\z/] - Sagar Pandya
如果您想使用 slice,那么可以使用 'solution_10'.slice(/\d+\z/) - Sagar Pandya
5个回答

7
使用 String#split 方法。
'solution_10'.split('_').last #will return original string if no underscore present
#=> "10"

'solution_10'.split('_')[1] #will return nil if no underscore present
#=> "10"

请注意,如果字符串中不包含下划线,则 split('_').last 将返回该字符串本身。在这种情况下,您可以使用 split('_')[1] 代替,以使其返回 nil - Stefan

6
"solution_10"[/(?<=_).*/]
#⇒ "10"

或者只需要获取直到行末的数字:
"solution_10"[/\d+\z/]
#⇒ "10"

5
我似乎无法理解如何做到这一点。
首先,slice和其快捷方式[]可以以许多方式使用。一种方式是提供一个开始索引和一个长度:
'hello'[2, 3] #=> "llo" # 3 characters, starting at index 2
#  ^^^

如果您事先知道长度,可以使用该变体。但是,由于字符串中的数字部分可以是101001000,因此您不知道长度。

另一种方法是提供范围,表示开始结束索引:

'hello'[2..3] #=> "ll"  # substring from index 2 to index 3
#  ^^

在这种情况下,Ruby会为您确定长度。您还可以提供负索引以从末尾计数。-1是最后一个字符,-2是倒数第二个字符,依此类推。
所以我的问题是如何摆脱下划线之前的所有字符,我只想要下划线后面的数字。
我们必须获取下划线的index
s = "solution_10"
i = s.index('_') #=> 8

现在我们可以通过以下方式获取从该索引到最后一个字符的子字符串:

s[i..-1] #=> "_10"

显然,我们错了一位,所以让我们加1:

s[i+1..-1] #=> "10"

请注意,这种方法不一定会返回一个数字(或数字字符串),它只会返回第一个下划线后面的所有内容:


就是这样。

s = 'foo_bar'
i = s.index('_') #=> 3
s[i+1..-1]       #=> "bar"

如果字符串不包含下划线,它也会完全失败,因为i将会是nil
s = 'foo'
i = s.index('_') #=> nil
s[i+1..-1]       #=> NoMethodError: undefined method `+' for nil:NilClass

为了提供更强大的解决方案,您可以像其他答案中所示,将正则表达式传递给slice / []。下面是一个版本,它匹配字符串末尾的下划线加数字。数字部分被捕获并返回:

"solution_10"[/_(\d+)\z/, 1] #=> "10"
#              _          literal underscore
#               (   )     capture group (the `1` argument refers to this)
#                \d+      one or more digits
#                    \z   end of string

非常感谢您抽出时间写下如此详细的解释 :) 这对我帮助很大。 - Saadia
当前的 Rubocop 喜欢使用在范围结尾处不带任何内容的切片来表示直到结尾而不是 -1,例如 s[i+1..]。 - Jimi Kimble

4

另一种方式:

'solution_10'[/\d+/]
#=> "10"

1
括号是多余的。如果它们应该是一个捕获组,你必须将它们移动到正则表达式内部。但这也不是必需的。 - Stefan
有了@Stefan提出的修复,这必须是最简单的解决方案。它的优点是它可以与“my_solution_10”一起使用。'solution_10'.gsub(/\D/,'') #=> "10"是另一面。 - Cary Swoveland

2
为什么不直接利用正则表达式呢?
"solution_10".scan(/\d+/).last
#=> "10"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接