2

我有一串交替的数字和字母。我想用它前面的字母数替换每个字符。例如,2a3b应该返回aabbb.

首先,如果我这样做:

"2a3b".scan(/(\d)(.)/) do |count, char|
  puts char * count.to_i
end 

我得到:

aa
bbb

但是,如果我这样做:

"2a3b".gsub(/(\d)(.)/) do |count, char|
  char * count.to_i
end 

我收到一个错误:

NoMethodError: undefined method `*' for nil:NilClass

它们不应该表现相同吗(更新:我的意思是,接受捕获组作为块参数)?

更新:(解决方法,有效)

"2a3b".gsub(/(\d)(.)/) do |match|
  $2 * $1.to_i
end 

返回:

"aabbb"

正如预期的那样。

4

2 回答 2

5

不,他们的行为不一样。gsub 的块形式只接受一个参数,因此第二个参数将为 nil,因此您的错误。见http://ruby-doc.org/core-2.1.4/String.html#method-i-gsub

使用示例:"hello".gsub(/./) {|s| s.ord.to_s + ' '}

在块形式中,当前匹配字符串作为参数传入,$1、$2、$`、$&、$'等变量会被适当设置。块返回的值将替换每次调用的匹配项。

结果继承了原始字符串或任何提供的替换字符串中的任何污染。

于 2017-01-13T23:31:59.450 回答
0

不,它们是两种不同的方法,做不同的事情。

请参阅http://ruby-doc.org/core-2.2.2/String.html#gsub-methodhttp://ruby-doc.org/core-2.2.2/String.html#scan-method

在抽象中,scan 更多的是用于查找字符串/表达式中的模式,(并使用块,以某种方式格式化它们)而 gsub 更多的是关于对字符串中的模式进行替换。

于 2017-01-13T23:33:05.213 回答