Labelled text file parsing

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!

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:

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!

CBlair1986 wrote:

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

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
Ruby Code & Style - 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

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 Gray 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

···

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

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!

CBlair1986 wrote:

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.

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

William James wrote:

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
}

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