我正在从文件中读取一些内容并使用正则表达式和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
中的内容格式正确。
答案 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
。