我正在尝试搜索一堆我想过滤的打印语句,如下所示:
其中我只想要那些没有value.stringValue()。value()。
最后,我想用value.stringValue()将这些行替换为value.stringValue()。value()。
我不知道为什么我目前的代码不起作用?
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
答案 0 :(得分:1)
问题是您没有将更改的行写回同一文件或新文件。要将它们写入同一文件,请将文件读入数组,更改数组,然后将其写回相同或不同的文件(后者更为谨慎)。这是使用几行代码完成此操作的一种方法。
<强>代码强>
fin_name
和fout_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 }