This is why "parsable" data has a delimiter. Still certainly possible to parse, but ups the difficulty.
–
jordanmNov 28 '12 at 6:10

If I had a vote, I'd definitely vote for a csv or other such type, but as it stands I'm stuck with this.
–
JBWhitmoreNov 28 '12 at 6:15

1

It just an opinion: parse it as a fixed size fields. It seems to be so.
–
crow16384Nov 28 '12 at 6:23

I see the columns are separated by two consecutive spaces, so if you try line.split(' '), I think you'll get something useful. Moreover, all the columns have their fixed number of characters - that may come to help too.
–
0605002Nov 28 '12 at 6:25

@g.d.d.c Yeah, I also said that. The key is the two-space-separator and fixed-width-columns.
–
0605002Nov 28 '12 at 6:43

And I think that correctly identifies the columns w/o data; and keeps the remaining columns "together" enough to be trivially parseable from here. I'll leave this open for a bit in case anyone else sees something wrong or a better way of doing these kinds of things.

Pyparsing returns a ParseResults data structure that can be used as a simple list, or as a dict with keys or an object with attributes if names are given to any of the parser elements. In the sample code, I show how you can use the field names to access the parsed data values for moonrise and moonset. Uncomment the call to vals.dump() to see all the valid field names and values for each line.

Pyparsing's default behavior is to implicitly skip over whitespace while matching elements of the parser, so we have to disable this with calls to leaveWhitespace on selected pieces of the parser. In your given data set, it looked like moonrise and moonset times were the only ones that might be blank, but this parser will detect any missing time, and report it as None. (I wasn't sure what was desired for the rightmost fields, left as an exercise for the OP.)