ruby 正则表达式扫描和 gsub 以不同方式处理块中的捕获组

ruby regex scan and gsub work differently with capture groups in blocks

我有一串交替的数字和字母。我想用它前面的字母数替换每个字符。例如,2a3b 应该 return 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|
   * .to_i
end 

returns:

"aabbb"

符合预期。

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

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

In the block form, the current match string is passed in as a parameter, and variables such as , , $`, $&, and $' will be set appropriately. The value returned by the block will be substituted for the match on each call.

The result inherits any tainting in the original string or any supplied replacement string.

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

http://ruby-doc.org/core-2.2.2/String.html#gsub-method and http://ruby-doc.org/core-2.2.2/String.html#scan-method

在摘要中,scan 更多地用于查找 strings/expressions 中的模式(并使用块,以某种方式格式化它们),而 gsub 更多地用于对字符串中的模式进行替换。