选择性替换printf语句

时间:2014-04-23 18:25:15

标签: ruby

我正在尝试搜索一堆我想过滤的打印语句,如下所示:

  1. 我想选择所有dbg_printfs
  2. 在所有这些中,我想选择那些具有value.stringValue()的
  3. 其中我只想要那些没有value.stringValue()。value()

  4. 最后,我想用value.stringValue()将这些行替换为value.stringValue()。value()。

  5. 我不知道为什么我目前的代码不起作用?

        fileObj = File.new(filepath, "r")
        while (line = fileObj.gets)
        line.scan(/dbg_printf/) do
          line.scan(/value.stringValue()/) do
             if !line.scan(/\.value\(\)/)
               line.gsub!(/value.stringValue()/, 'value.stringValue().value()')
             end
          end
        end
        fileObj.close
    

2 个答案:

答案 0 :(得分:1)

问题是您没有将更改的行写回同一文件或新文件。要将它们写入同一文件,请将文件读入数组,更改数组,然后将其写回相同或不同的文件(后者更为谨慎)。这是使用几行代码完成此操作的一种方法。

<强>代码

fin_namefout_name分别是输入和输出文件的名称(带路径)。

def filter_array(fin_name, fout_name)
  arr_in = File.readlines(fin_name)
  arr_out = arr_in.map { |l| (l.include?('dbg_printfs') &&
      l.include?('value.stringValue()')                 &&
      !l.include?('value.stringValue().value()')) ? 
    'value.stringValue() to value.stringValue().value()' : l }
  File.open(fout_name, 'w') { |f| f.puts arr_out }
end

因为您正在阅读代码文件,所以它们不会太大,以至于一次将它们全部读入内存将是一个问题。

示例

首先,我们将构建一个输入文件:

array = ["My dbg_printfs was a value.stringValue() as well.",
         "Her dbg_printfs was a value.stringValue() but not " +
            "a value.stringValue().value()",
         "value.stringValue() is one of my favorites"]

fin_name  =  'fin'
fout_name =  'fout'
File.open(fin_name, 'w') { |f| f.puts array }

我们可以通过以下方式确认其内容:

File.readlines(fin_name).map { |l| puts l }

现在尝试一下:

filter_array(fin_name, fout_name)

阅读输出文件以查看它是否有效:

File.readlines(fout_name).map { |l| puts l }
  #=> value.stringValue() to value.stringValue().value()
  #   Her dbg_printfs was a value.stringValue() but not a value.stringValue().value()
  #   value.stringValue() is one of my favorites

看起来不错。

<强>解释

def filter_array(fin_name, fout_name)
  arr_in = File.readlines(fin_name)
  arr_out = arr_in.map { |l| (l.include?('dbg_printfs') &&
      l.include?('value.stringValue()')                 &&
      !l.include?('value.stringValue().value()')) ? 
    'value.stringValue() to value.stringValue().value()' : l }
  File.open(fout_name, 'w') { |f| f.puts arr_out }
end

对于上面的例子,

arr_in = File.readlines('fin')
  #=> ["My dbg_printfs was a value.stringValue() as well.\n",
  #    "Her dbg_printfs was a value.stringValue() but not a value.stringValue().value()\n",
  #    "value.stringValue() is one of my favorites\n"]

传递给arr_in的{​​{1}}的第一个元素是:

map

我们有

l = "My dbg_printfs] was a value.stringValue() as well."

以便元素映射到:

l.include?('dbg_printfs')                  #=> true
l.include?('value.stringValue()')          #=> true
!l.include?('value.stringValue().value()') #=> true

其他两个元素都没有被此字符串替换,因为

"value.stringValue() to value.stringValue().value()"

!l.include?('value.stringValue().value()') #=> false

分别。因此,

l.include?('dbg_printfs')                  #=> false

最后一步是将arr_out = arr_in.map { |l| (l.include?('dbg_printfs') && l.include?('value.stringValue()') && !l.include?('value.stringValue().value()')) ? 'value.stringValue() to value.stringValue().value()' : l } #=> ["value.stringValue() to value.stringValue().value()", # "Her dbg_printfs was a value.stringValue() but not a value.stringValue().value()\n", # "value.stringValue() is one of my favorites\n"] 写入输出文件。

答案 1 :(得分:1)

首先,您的问题似乎是您希望更改从gets返回的字符串以更改文件的内容。字符串和文件之间实际上并没有这种关系。您需要明确地将修改写入文件。就个人而言,我可能会写这样的代码:

modified_contents = IO.readlines(filepath).map do |line|
  if line =~ /dbg_printf/
    # This regex just checks for value.stringValue() when not followed by .value()
    line.gsub /value\.stringValue\(\)(?!\.value\(\))/, 'value.stringValue().value()'
  else
    line
  end
end
File.open(filepath, 'w') {|file| file.puts modified_contents }