Labelled text file parsing


#1

Hi. What I’d like to do is to take a file like so:

Apple
Color: Red
Peel: Yes
Has Core: Yes

Orange
Color: Orange
Peel: Yes
Has Core: No

and go through it, line by line, assigning the ‘Apple’ and ‘Orange’
lines to a name attribute on different hashes, and then using the name
before the colons such as ‘Color’ and ‘Peel’ as keys for the respective
values.

I’m just asking for a bit of help and guidance, as I’m still not very
keen on using regular expressions that comfortably and all.

Thanks to anyone who helps!


#2

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

An easier way to do this might be to use YAML (http://www.yaml.org)
which is built into Ruby now.
Though, if you’d like this to be more of a project some very simple
RegEx work and running through the text line by line wouldn’t be too
difficult.

On Dec 1, 2005, at 5:57 PM, CBlair1986 wrote:

Has Core: No
Thanks to anyone who helps!

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Darwin)

iD8DBQFDj6vuG9xIoXK+giARAqZWAKDS2jBxdT7uZirjCwY9fDn2kUaTCgCfZoch
VE2fdfkPtrL1k1JOnR3JSis=
=9VvV
-----END PGP SIGNATURE-----


#3

CBlair1986 wrote:

Has Core: No
How is this file created? It looks very much like YAML, and Ruby ships
with a YAML parser, so if you have any say over the file format, make it
valid YAML.

Something like this:

Apple :
Color: Red
Peel: Yes
Has Core: Yes

Orange :
Color: Orange
Peel: Yes
Has Core: No

James

http://www.ruby-doc.org - Ruby Help & Documentation
http://www.artima.com/rubycs/ - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools


#4

CBlair1986 wrote:

Has Core: No

and go through it, line by line, assigning the ‘Apple’ and ‘Orange’
lines to a name attribute on different hashes, and then using the name
before the colons such as ‘Color’ and ‘Peel’ as keys for the respective
values.

table = {}
ARGF.each { |line| line.strip!
next if line == “”
fields = line.split( /: +/ )
if fields.size == 1
$fruit = fields.first
table[$fruit] = {}
else
table[$fruit][fields.first] = fields.last
end
}

p table


#5

William J. wrote:

end
}

OK, I saw your $fruit rationale after removing $ :wink:

Here’s a variation:

#---------------------------------------------------
table = {}; fruit = nil

IO.foreach(‘fruit.txt’) do |line|
k,v = line.strip.split(/: +/)
k or next
v and table[fruit][k] = v or table[fruit=k] = {}
end
#---------------------------------------------------

daz


#6

On Dec 1, 2005, at 7:57 PM, CBlair1986 wrote:

Has Core: No
Thanks to anyone who helps!
I’m in a terrible rush, but see if this code gets you going. Ask
questions if you have them and I’ll answer later…

James Edward G. II

#!/usr/local/bin/ruby -w

require “pp”

data = Hash.new

DATA.each_line("") do |para|
if para.sub!(/\A *(.+?) *\n/, “”)
data[$1] = Hash[para.split("\n").map { |line| line.split(/:
\s
/) }.flatten]
end
end

pp data

END
Apple
Color: Red
Peel: Yes
Has Core: Yes

Orange
Color: Orange
Peel: Yes
Has Core: No