我有一个我正在阅读的文件,其中包含以下内容:
13:37:08:634 Verify
PerformService
13:37:08:634 Buffer
***********************************************
* INPUTbuffer follows
***********************************************
ababababa
cdcdcdcdc
13:37:08:666 Buffer
***********************************************
* INPUT XML buffer follows
***********************************************
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE SYSTEM 'c:\'>
<App version="3.7.2" payloadID="Wed Dec 11 13:37:08 EST 2013.processId.0.5322738932043712@172.16.57.149" timestamp="Wed Dec 11 13:37:08 EST 2013">
<header>
<from>
<client>
HTML
</client>
<NameAssertion>
//... etc
</App>
我正在努力想出一个可以从
中选择所有内容的正则表达式***********************************************
* INPUT XML buffer follows
***********************************************
至</App>
-
更新1 - 工作代码
bufferBlocks = []
if criteria["buffers"] then
bufferBlock = ""
File.foreach("#{options[:source]}") do |li|
bufferBlock << li if (li['* INPUT XML buffer follows'] .. li[%r(</momentum)])
end
bufferBlocks.push(bufferBlock)
end
#...
buffer << bufferBlocks.shift.to_s.squeeze("\n")
File.write("#{options[:dest]}", buffer)
答案 0 :(得分:2)
这是Ruby的“触发器”AKA ..
运营商闪耀的地方。
从以下内容开始:
File.foreach('test.txt') do |li|
puts li if (li['INPUTbuffer follows'] .. li[%r(</App)])
end
如果我从文件中读取您的文本示例,我会得到:
* INPUTbuffer follows
***********************************************
ababababa
cdcdcdcdc
13:37:08:666 Buffer
***********************************************
* INPUT XML buffer follows
***********************************************
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE SYSTEM 'c:\'>
<App version="3.7.2" payloadID="Wed Dec 11 13:37:08 EST 2013.processId.0.5322738932043712@172.16.57.149" timestamp="Wed Dec 11 13:37:08 EST 2013">
<header>
<from>
<client>
HTML
</client>
<NameAssertion>
//... etc
</App>
请注意,它缺少“INPUTbuffer ...”行之前的行。要让它在需要一些正则表达式之前选择该行,并改变文件的读取方式。不是使用逐行读取的foreach
,而是必须将文件读入缓冲区,这会导致可伸缩性问题。
快速而肮脏的解决方法是将分隔字符串填充到内容前面。像这样:
buffer = ('*' * 47) + "\n"
File.foreach('test.txt') do |li|
buffer << li if (li['INPUTbuffer follows'] .. li[%r(</App)])
end
puts buffer
现在输出你想要的东西,但是有点欺骗。输出现在看起来像:
*********************************************** * INPUTbuffer follows *********************************************** ababababa cdcdcdcdc ...
我提到了可伸缩性问题。想象一下,如果您尝试读取的文件不是几百行,而是数千或数百万,那么您的系统会发生什么。在搜索之前将其拉入缓冲区可能会使您的代码或计算机速度降低到无法使用的程度。这是一种情况,当代码从开发转移到生产中时,开发测试文件被剥离到其本质,然后突然代码看到了GB范围内的完整数据库转储或日志。
相反,使用foreach
或其中一个工作相似,此代码将有选择地拉出所需的行并将它们附加到缓冲区。如果文件中存在多个块,则它们也将被捕获,而无需其他代码。在这种情况下,如何插入额外的标题行和/或处理块将留给你弄清楚。