如何在写入另一个文件时保留内容格式?

时间:2017-03-20 17:09:20

标签: ruby regex file

我正在从文件中读取一些内容并使用正则表达式和scan来丢弃文件中的一些内容并将内容写入另一个文件。

如果我查看新写入的文件,它在文件中有转义字符和"\n",而不是实际的新行。

filea.txt是:

test
in run
]
}
end

我使用以下内容获取'test'和'end'之间的内容:

file = File.open('filea.txt', 'r')
result = file.read    
regex = /(?<=test) .*?(?=end)/mx
ans = result.scan(regex)

ans写入fileb.txt等新文件中:

in run'\"\n            ]\n          }

但是,如果我尝试编写整个result,那么它在fileb.txt中的内容格式正确。

1 个答案:

答案 0 :(得分:0)

您的问题不明确且需要解决,但您使用read的方式会导致可伸缩性问题。

以下是如何在不使用read的情况下完成相同类型的任务:

content = []
DATA.each_line do |li|
  marker = li.lstrip
  if marker =~ /^in run/i .. marker =~ /^end of file/i
    content << li
  end
end
content # => ["in run\n", "]\n", "}\n", "end of file\n"]

__END__
test file
in run
]
}
end of file

..(elipsis)是Ruby(和其他语言)中的多功能工具。我们用它来定义范围,但也可以用它来触发逻辑状态。在这种情况下,我正在以第二种形式使用它,一个“触发器”。

当Ruby运行代码时,它会检查

marker =~ /^in run/i`

如果为false,则if失败,代码继续。如果

marker =~ /^in run/i

成功后,Ruby会记住它成功并立即测试

marker =~ /^end of file/i

如果失败,Ruby将落入if块并执行块中的任何操作,然后继续正常运行。

each_line的下一个循环将点击if个测试,..会记住

marker =~ /^in run/i

先前成功并立即测试第二个条件。如果是真的,它会进入块并再次将自身重置为false,这样任何后续循环都将失败,直到

marker =~ /^in run/i

再次返回true。

这种逻辑非常强大,可以轻松构建可扫描大文件的代码,并提取部分文件。

还有其他方法可以做到,但它们通常会遇到更混乱的逻辑。

在示例代码中,我也使用了__END__,它也有一些很少见的魔法。如果您不了解发生的情况,请阅读__END__DATA

如果您正在处理GB或TB范围内的文件,并且您正在抓取大量内容,那么在您的数据收集阵列content中不会积累太多内容可能是明智之举。一个小小的调整将阻止这种情况发生:

if marker =~ /^in run/i .. marker =~ /^end of file/i
  content << li
  next
end
unless content.empty?
  # do something that clears content:
end

在此代码中我使用的是DATA.each_line。在现实生活中,你想要使用File.foreach