Ruby:你如何搜索子字符串,并在其中增加一个值?

时间:2013-10-17 22:09:10

标签: ruby

我正在尝试通过查找此字符串来更改文件:

<aspect name=\"lineNumber\"><![CDATA[{CLONEINCR}]]>

并用递增的数字替换{CLONEINCR}。这是我到目前为止所做的:

file = File.open('input3400.txt' , 'rb')
contents = file.read.lines.to_a
contents.each_index do |i|contents.join["<aspect name=\"lineNumber\"><![CDATA[{CLONEINCR}]]></aspect>"] = "<aspect name=\"lineNumber\"><![CDATA[#{i}]]></aspect>" end
file.close

但这似乎永远存在 - 我在某处有无限循环吗?

注意:我的文本文件长533,952行。

2 个答案:

答案 0 :(得分:1)

您反复连接contents的所有元素,进行替换,并丢弃结果。每一行都会发生一次,所以难怪它需要很长时间。

最简单的解决方案是将整个文件读入单个字符串并使用gsub来修改内容。在您的示例中,您将(基于零的)文件行号插入CDATA。我怀疑这是一个错误。

此代码将所有<![CDATA[{CLONEINCR}]]>替换为<![CDATA[1]]><![CDATA[2]]>等,并为找到的每个匹配CDATA增加数字。修改后的文件将发送到STDOUT。希望这就是你所需要的。

File.open('input3400.txt' , 'r') do |f|
  i = 0
  contents = f.read.gsub('<![CDATA[{CLONEINCR}]]>') { |m|
    m.sub('{CLONEINCR}', (i += 1).to_s)
  }
  puts contents
end

答案 1 :(得分:0)

如果您想要的是将CLONEINCR替换为行号,这就是您上面的代码看起来正在尝试做的事情,那么这将有效。否则请参阅鲍罗丁的答案。

output = File.readlines('input3400.txt').map.with_index do |line, i|
  line.gsub "<aspect name=\"lineNumber\"><![CDATA[{CLONEINCR}]]></aspect>",
    "<aspect name=\"lineNumber\"><![CDATA[#{i}]]></aspect>"
end
File.write('input3400.txt', output.join(''))

此外,您应该知道,当您将行读入contents时,您将创建与文件不同的String。您无法直接操作该文件。相反,您必须创建一个包含所需内容的新String,然后覆盖原始文件。