输出行以分隔ruby中的行

时间:2015-11-30 11:04:00

标签: ruby

我有一个文件,我搜索特定的行,如下所示:

<ClCompile Include="..\..\..\Source\fileA.c" />
<ClCompile Include="..\..\..\Tests\fileB.c" />

在我的脚本中,我可以找到这些行并仅提取double qoutes之间的路径字符串。当我找到它们时,我将它保存到一个数组(我稍后在我的代码中使用)。它看起来像这样:

source_path_array = []

File.open(file_name) do |f|
    f.each_line {|line|
     if line =~ /<ClCompile Include="..\\/
      source_path = line.scan(/".*.c"/)

      ###### Add path to array ######
      source_path_array << source_path 
    end
  }
end

到目前为止,一切都好。稍后在我的脚本中,我将另一个文件中的数组输出到“Source Files”行:

f.puts "Source Files= #{source_path_array.flatten.join(" ")}"

结果是这样的:

Source Files= "..\..\..\Source\fileA.c" "..\..\..\Tests\fileB.c"

我希望以这种形式输出:

Source Files=..\..\..\Source\fileA.c
Source Files=..\..\..\Tests\fileB.c

正如您所看到的,每个路径都在一个单独的行中,字符串“Source Files”之前也没有双引号。任何的想法?也许我对阵列的概念也不是最好的。

2 个答案:

答案 0 :(得分:1)

然后不要使用#join。使用#each#map。此外,您可以使用#gsub删除引号:

source_path_array.flatten.each do |path|
  f.puts "Source Files=#{path.gsub(/(^"|")$/, '')}"
end

f.puts source_path_array.flatten.map do |path|
  "Source Files=#{path.gsub(/(^"|")$/, '')}"
end.join("\n")

第二个版本的I / O效率可能更高。

要使其工作(并且作为问题第二部分的答案),source_path_array应包含字符串。这是获得这个的方法:

regex = /<ClCompile Include="(\.\.\\[^"]+)/
File.open(file_name) do |f|
  f.each_line do |line|
    regex.match(line) do |matches|
      source_path_array << matches[1] 
    end
  end
end

如果您不介意一次读取内存中的整个文件,则会略短:

regex = /<ClCompile Include="(\.\.\\[^"]+)/
File.read(file_name).split(/(\r?\n)+/).each do |line|
  regex.match(line) do |matches|
    source_path_array << matches[1] 
  end
end

最后,这是使用Nokogiri的一个例子:

require 'nokogiri'
source_path_array = File.open(file_name) do |f|
  Nokogiri::XML(f)
end.css('ClCompile[Include^=..\\]').map{|el| el['Include']}

所有这些都会解析引号,因此您可以从第一部分中删除#gsub

现在一起:

require 'nokogiri'
f.puts File.open(file_name) do |source|
  Nokogiri::XML(source)
end.css('ClCompile[Include^=..\\]').map do |el|
  "Source Files=#{el['Include']}"
end.join("\n")

并且当一次(单个#map)可行时,不要循环两次(#join然后#reduce):

require 'nokogiri'
f.puts File.open(file_name) do |source|
  Nokogiri::XML(source)
end.css('ClCompile[Include^=..\\]').reduce('') do |memo, el|
  memo += "Source Files=#{el['Include']}\n"
end.chomp

答案 1 :(得分:0)

感谢@FélixSaparelli:

以下对我有用:

  source_path_array.flatten.each do |path|
    f.puts "Source Files=#{path.delete('"')}"
   end