搜索/替换怪异

时间:2011-07-05 00:54:58

标签: ruby regex

为什么这段代码只修改数组中的最后一个文件?这些文件都是我的用户可读和可写的。

%w(views/layout.rhtml views/admin/layout.rhtml).each do |file|
  text = File.read(file)
  File.open(file, 'w+') do |f|
    f << text.gsub(/\?v=(\d+)/, "?v=#{$1.to_i + 1}")
  end
end

1 个答案:

答案 0 :(得分:4)

你的问题是你没有使用gsub的阻止形式,所以$1并没有像你想象的那样设置类似的全局变量。从精细的手册:

  

如果 replacement 是一个字符串,它将替换匹配的文本。它可能包含对\\d形式的模式捕获组的反向引用,其中 d 是一个组号,或\\k<n>,其中 n 是一个组名。如果它是双引号字符串,则两个反向引用都必须以额外的反斜杠开头。但是,在替换中,特殊匹配变量(例如&amp; $)将不会引用当前匹配

  

在块形式中,当前匹配字符串作为参数传递,变量如$1$2$&$’将适当设置。块返回的值将替换每次调用的匹配。

Bolding mine。另外,我遗漏了反击全球:

$`

为了避免Markdown的问题(如果有人知道如何在内联代码块中获得反引号,我会很感激指针)。

如果你这样做:

%w(views/layout.rhtml views/admin/layout.rhtml).each do |file|
  text = File.read(file)
  File.open(file, 'w+') do |f|
    f << text.gsub(/\?v=(\d+)/) { "?v=#{$1.to_i + 1}" }
  end
end

我想你会得到你正在寻找的结果。