# File data extraction

**URL:** <https://www.ruby-forum.com/t/file-data-extraction/191095>\
**Category:** Ruby\
**Created:** [July 5, 2010, 10:48am UTC](https://www.ruby-forum.com/t/file-data-extraction/191095 "2010-07-05T10:48:55Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 5, 2010, 10:48am UTC](https://www.ruby-forum.com/t/file-data-extraction/191095/1 "2010-07-05T10:48:55Z")

</div>

Hi

I have a file with the following format (example):

Save Format v3.0(19990112)  
@begin Libraries  
“felles.pbl” “”;  
@end;  
@begin Objects  
“n\_cst\_xml\_utils.sru” “felles.pbl”;  
“n\_melding.sru” “felles.pbl”;  
@end;

The data in the two begin/end blocks are lists, which may be longer than  
shown.

I’d like to extract an array of the filenames (first quote) in the  
@begin  
Objects … @end; block.  
For the example above this should return [“n\_cst\_xml\_utils.sru”,  
“n\_melding.sru”]

My initial idea was to treat the whole thing as one long string, and  
extract  
the part within the being-end-block by using regexp, converting the  
result  
back to individual lines (split ‘\n’) and doing array.map and regexp to  
single out the name in the first quote on each line.  
But I keep hitting the wall, especially with the first step in this  
approach… :o(

I know this should be easily done in a couple of lines of code, but I  
can’t  
get it right.

Appreciate any help!

Best regards,  
Rolf

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 5, 2010, 12:12pm UTC](https://www.ruby-forum.com/t/file-data-extraction/191095/2 "2010-07-05T12:12:18Z")

</div>

Rolf P. wrote:

> My initial idea was to treat the whole thing as one long string, and  
> extract  
> the part within the being-end-block by using regexp, converting the  
> result  
> back to individual lines (split ‘\n’) and doing array.map and regexp to  
> single out the name in the first quote on each line.  
> But I keep hitting the wall, especially with the first step in this  
> approach… :o(

How about this for starters:

p src.scan(/^@begin(.\*?)^@end;/m)

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 5, 2010, 1:53pm UTC](https://www.ruby-forum.com/t/file-data-extraction/191095/3 "2010-07-05T13:53:19Z")

</div>

Thanks Brian, that helped me a lot ! :o)

The code now looks like this:

filenames = File.open(filename).readlines.join.scan(/^@begin  
Objects\n(._?)^@end;/m)[0][0].split("\n").map{|l|  
l.scan(/"(._?)"/)[0][0]}  
Probably far from optimal, but it seems to do the trick.

Best regards,  
Rolf

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 5, 2010, 2:07pm UTC](https://www.ruby-forum.com/t/file-data-extraction/191095/4 "2010-07-05T14:07:28Z")

</div>

Rolf P. wrote:

> The code now looks like this:
> 
> filenames = File.open(filename).readlines.join.scan(/^@begin  
> Objects\n(._?)^@end;/m)[0][0].split("\n").map{|l|  
> l.scan(/"(._?)"/)[0][0]}  
> Probably far from optimal, but it seems to do the trick.

That’s the most important thing 🙂

I actually misread your example. If there’s only one @begin Objects  
section, then ‘scan’ is overkill; a simple regexp match will do.

res = if File.read(filename) =~ /^@begin Objects$(._?)^@end;$/m  
$1.scan(/^\s_"(.\*?)"/).map { |r| r.first }  
end

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 5, 2010, 5:51pm UTC](https://www.ruby-forum.com/t/file-data-extraction/191095/5 "2010-07-05T17:51:35Z")

</div>

2010/7/5 Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I actually misread your example. If there’s only one @begin Objects  
> section, then ‘scan’ is overkill; a simple regexp match will do.
> 
> res = if File.read(filename) =~ /^@begin Objects$(._?)^@end;$/m  
> $1.scan(/^\s_"(.\*?)"/).map { |r| r.first }  
> end

If files are large than the line based approach is usually more  
feasible. In this case you can use the flip flop operator in an if  
condition to select the lines we want:

17:31:49 Temp$ ./lextr.rb  
[“n\_cst\_xml\_utils.sru”, “n\_melding.sru”]  
17:48:32 Temp$ cat lextr.rb  
#!/bin/env ruby19

ar = []

DATA.each\_line do |line|  
if /^@begin Objects/ =~ line … /^end;/ =~ line  
name = line[/^\s\*“([^”]\*)"/, 1] and ar \<\< name  
end  
end

p ar

**END**  
Save Format v3.0(19990112)  
@begin Libraries  
“felles.pbl” “”;  
@end;  
@begin Objects  
“n\_cst\_xml\_utils.sru” “felles.pbl”;  
“n\_melding.sru” “felles.pbl”;  
@end;  
17:49:30 Temp$

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 7, 2010, 11:36am UTC](https://www.ruby-forum.com/t/file-data-extraction/191095/6 "2010-07-07T11:36:38Z")

</div>

Robert:  
The use of flip flop operator opened a new door for me. Didn’t know of  
this  
before…  
And new knowledge is the best knowledge! :o)

w\_a\_x\_man:  
I can’t believe I didn’t think of the possibility to use a simple split  
instead of a scan to extract the filenames between the first two  
quotation  
marks!

Thanks to all for the great input I’ve gotten on this issue!  
:o)

Best regards,  
Rolf

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 5, 2010, 8:25pm UTC](https://www.ruby-forum.com/t/file-data-extraction/191095/7 "2010-07-05T20:25:34Z")

</div>

On Jul 5, 3:48 am, Rolf P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> @begin Objects  
> “n\_melding.sru”]
> 
> Appreciate any help!
> 
> Best regards,  
> Rolf

puts DATA.read.scan(/^@begin Objects(.\*?)^@end;/m).flatten.  
map{|s| s.strip.to\_a}.flatten.map{|s| s.split(/"/)[1]}

**END**  
Save Format v3.0(19990112)  
@begin Libraries  
“felles.pbl” “”;  
@end;  
@begin Objects  
“n\_cst\_xml\_utils.sru” “felles.pbl”;  
“n\_melding.sru” “felles.pbl”;  
@end;  
@begin Libraries  
“felles.pbl” “”;  
@end;  
@begin Objects  
“n\_cst\_xml\_utils.sru” “felles.pbl”;  
“n\_melding.sru” “felles.pbl”;  
@end;
