I’m hoping someone can jog my memory here. Say I’ve got a file which
contains the keywords “START” and “END”, with several lines in between.
Suppose I want to operate on everything between START and END (inclusive
or not, doesn’t really matter, I don’t think).
Naively, I would do one of a couple things: either use a multiline
regexp, or read the file until START is encountered, and set some sort
of “readthis” flag which signals the program to operate on the lines
until END is encountered, at which point the flag is unset.
However… I’m pretty sure that, somewhere, sometime, I saw some much
more elegant way of doing this in ruby. I said “neat!”, and promptly
forgot about it. Something involving ranges, maybe? Anybody have an idea
what I might have been thinking of, or am I misremembering?
Any help would be much appreciated. This is a great newsgroup and
mailing list; I only wish I had time to read it all.
I’m hoping someone can jog my memory here. Say I’ve got a file which
contains the keywords “START” and “END”, with several lines in between.
Suppose I want to operate on everything between START and END (inclusive
or not, doesn’t really matter, I don’t think).
Naively, I would do one of a couple things: either use a multiline
regexp, or read the file until START is encountered, and set some sort
of “readthis” flag which signals the program to operate on the lines
until END is encountered, at which point the flag is unset.
Why not something like this?
parsing = false
File::open(‘path/to/file’).readlines.each { |line|
next unless parsing || parsing = (line =~ /^START$/)
break if line =~ /^END$/
handle parsing
…
}
It doesn’t use a range, but it’s relatively concise.
However… I’m pretty sure that, somewhere, sometime, I saw some much
more elegant way of doing this in ruby. I said “neat!”, and promptly
forgot about it. Something involving ranges, maybe? Anybody have an idea
what I might have been thinking of, or am I misremembering?
Any help would be much appreciated. This is a great newsgroup and
mailing list; I only wish I had time to read it all.
However… I’m pretty sure that, somewhere, sometime, I saw some much
more elegant way of doing this in ruby. I said “neat!”, and promptly
forgot about it. Something involving ranges, maybe? Anybody have an idea
what I might have been thinking of, or am I misremembering?
You mean like this example from ruby-talk [73674] ?
while( line = gets )
if /BEGIN:VCARD/ =~ line … /END:VCARD/ =~ line
puts line
end
end
while line = gets
if line =~ /^START$/ … /^END$/
puts line
end
end
(‘puts line’ will ping all lines between and including the START and END
lines)
Regards,
Brian.
···
On Tue, Jun 24, 2003 at 11:02:58AM +0900, Jim Bob wrote:
I’m hoping someone can jog my memory here. Say I’ve got a file which
contains the keywords “START” and “END”, with several lines in between.
Suppose I want to operate on everything between START and END (inclusive
or not, doesn’t really matter, I don’t think).
Naively, I would do one of a couple things: either use a multiline
regexp, or read the file until START is encountered, and set some sort
of “readthis” flag which signals the program to operate on the lines
until END is encountered, at which point the flag is unset.
However… I’m pretty sure that, somewhere, sometime, I saw some much
more elegant way of doing this in ruby. I said “neat!”, and promptly
forgot about it. Something involving ranges, maybe? Anybody have an idea
what I might have been thinking of, or am I misremembering?
Thanks, everyone. That
line =~ /START/ … line =~ /END/
thing is exactly what I was trying to remember.
Thanks, Paul, too, for an implementation of one of the “naive” ways I
had mentioned which is, indeed, much nicer and more concise than the way
I had been doing it.
I’m hoping someone can jog my memory here. Say I’ve got a file which
contains the keywords “START” and “END”, with several lines in
between.
Suppose I want to operate on everything between START and END
(inclusive
or not, doesn’t really matter, I don’t think).
Naively, I would do one of a couple things: either use a multiline
regexp, or read the file until START is encountered, and set some sort
of “readthis” flag which signals the program to operate on the lines
until END is encountered, at which point the flag is unset.
However… I’m pretty sure that, somewhere, sometime, I saw some
much
more elegant way of doing this in ruby. I said “neat!”, and promptly
forgot about it. Something involving ranges, maybe? Anybody have an
idea
what I might have been thinking of, or am I misremembering?
while line = gets
if line =~ /^START$/ … /^END$/
puts line
end
end
(‘puts line’ will ping all lines between and including the START and END
lines)
There might be a hidden gotcha in your code if it worked for you: $_ will
be assigned during gets and this might have made it work (if at all).
However, it didn’t work for me:
irb(main):054:0* lines=“1\nSTART\nfoo\nEND\n2”
“1\nSTART\nfoo\nEND\n2”
irb(main):055:0>
irb(main):056:0* lines.each do |line|
irb(main):057:1* if line =~ /^START$/ … /^END$/
irb(main):058:2> puts line
irb(main):059:2> end
irb(main):060:1> end
START
“1\nSTART\nfoo\nEND\n2”
irb(main):061:0>
IMHO this is the correct solution:
irb(main):062:0* lines.each do |line|
irb(main):063:1* if /^START$/ =~ line … /^END$/ =~ line
irb(main):064:2> puts line
irb(main):065:2> end
irb(main):066:1> end
START
foo
END
“1\nSTART\nfoo\nEND\n2”
irb(main):067:0>
Regards
robert
···
On Tue, Jun 24, 2003 at 11:02:58AM +0900, Jim Bob wrote: