Happy Bye George Day!
I've been chipping away at a long-term project: investigating the
ephemeris. I think it would make a great way to continue exploring perl's
pattern-matching capabilities.
So I'll have a program that looks like this:
my $filename = 'eph3.txt';
open(my $fh, '<', $filename) or die "cannot open $filename: $!";
while (<$fh>) {
print $_;
}
close($fh)
# perl faulk10.pl
or
open(my $fh, '<', 'eph3.txt');
while (my $line = <$fh>) {
print $line;
}
close($fh)
# perl faulk7.pl
I'll want to have an explicit variable for the line, so I'll use the better
parts of the above.
The first thing I'll want to do is capture the first seven characters in a
line. We can assume that these will always be letters or spaces padded out
to the right.
After that, I want to strip away all the characters, as does the following
fortran routine. In this treatment $line would be inrec .
subroutine WasteNonDigits(inrec)
character*80 inrec
character*1 c1,c2
character*13 ValidDigits
data ValidDigits/'0123456789.-+'/
n=13
do i=1,80
c1=' '
c2=inrec(i:i)
do j=1,n
if(c2.eq.ValidDigits(j:j)) c1=c2
end do
inrec(i:i)=c1
end do
return
end subroutine
Ultimately, I want to populate an object that I think would be pretty tame
by perl standards.
This is the data set:
C:\MinGW\source>type eph3.txt
! yesterday
# another comment
Sun 18h 41m 55s -23? 5.4' 0.983 10.215 52.155 Up
Mercury 20h 2m 16s -22? 12.5' 1.102 22.537 37.668 Up
Venus 21h 55m 33s -14? 16.3' 0.795 39.872 11.703 Up
Moon 21h 17m 19s -15? 2.4' 62.4 ER 36.796 22.871 Up
Mars 18h 11m 59s -24? 6.1' 2.431 4.552 56.184 Up
Jupiter 20h 3m 35s -20? 49.4' 6.034 23.867 38.203 Up
Saturn 11h 32m 59s +5? 8.6' 9.018 -47.333 157.471 Set
Uranus 23h 21m 30s -4? 57.9' 20.421 48.328 -18.527 Up
Neptune 21h 39m 30s -14? 22.8' 30.748 38.963 16.599 Up
Pluto 18h 4m 34s -17? 44.5' 32.543 7.443 62.142 Up
C:\MinGW\source>
Thanks for your comment.
Dropping this reply in the outter reply structure. From the inner posts
it looks like you just are trying to learn regular expressions.
Therefore, the set of data would present a significant formatting project
to cut your teeth on. This is probably a good thing.
After a point you would look at this data and try to factor out the real
things you want here, instead of redundant groupings. The fact is that
you don't need to validate numbers, letters, locations in the parsing regular
expression as this can be done later.
What each data line is in reality is either a group of numbers or a group
of letters. The letters can only be at the end or beginning.
So beginning or end its either ^[a-z] or [a-z]$
In the middle its [\d.+-]
Put them together with an or '|' and you have the parsing regex. Its that simple.
Validate later if you really need to.
There is no need to make Mount Everest out of a mole hill.
This one's for free George.
sln
-----------------------------------------------------
use strict;
use warnings;
my @fldnames = ('fld01','fld02','fld03','fld04','fld05','fld06','fld07','fld08','fld09','fld10');
my @Records = ();
while (<DATA>)
{
# Strip leading/trailing white space's
s/^\s*//; s/\s*$//;
next if (!length());
# Parse regex, only get whats needed
my @rec = /(^\s*[a-z]+|[\d.+-]+|[a-z]+\s*$)/ig;
# Parse regex alternate, with look ahead
# ---------------------
# or
# my @rec = /(^\s*[a-z]+|[\d.+-]+|[a-z]+?(?=\s*$))/ig;
# ---------------------
# Validate record size
next if (@rec != 10);
# Store record into a hash struct, put ref into Records array
my %struct;
@struct{ @fldnames } = @rec;
push (@Records,\%struct);
# Some debug printing
print "\n$_\n";
print "@rec\n";
print "$_ = $struct{$_}\n" for (sort keys %struct);
}
# Do something with 'Records' structures
# ...
__DATA__
Sun 18h 41m 55s -23? 5.4' 0.983 10.215 52.155 Up
Mercury 20h 2m 16s -22? 12.5' 1.102 22.537 37.668 Up
Venus 21h 55m 33s -14? 16.3' 0.795 39.872 11.703 Up
Moon 21h 17m 19s -15? 2.4' 62.4 ER 36.796 22.871 Up
Mars 18h 11m 59s -24? 6.1' 2.431 4.552 56.184 Up
Jupiter 20h 3m 35s -20? 49.4' 6.034 23.867 38.203 Up
Saturn 11h 32m 59s +5? 8.6' 9.018 -47.333 157.471 Set
Uranus 23h 21m 30s -4? 57.9' 20.421 48.328 -18.527 Up
Neptune 21h 39m 30s -14? 22.8' 30.748 38.963 16.599 Up
Pluto 18h 4m 34s -17? 44.5' 32.543 7.443 62.142 Up
__END__
Output:
Sun 18h 41m 55s -23? 5.4' 0.983 10.215 52.155 Up
Sun 18 41 55 -23 5.4 0.983 10.215 52.155 Up
fld01 = Sun
fld02 = 18
fld03 = 41
fld04 = 55
fld05 = -23
fld06 = 5.4
fld07 = 0.983
fld08 = 10.215
fld09 = 52.155
fld10 = Up
Mercury 20h 2m 16s -22? 12.5' 1.102 22.537 37.668 Up
Mercury 20 2 16 -22 12.5 1.102 22.537 37.668 Up
fld01 = Mercury
fld02 = 20
fld03 = 2
fld04 = 16
fld05 = -22
fld06 = 12.5
fld07 = 1.102
fld08 = 22.537
fld09 = 37.668
fld10 = Up
Venus 21h 55m 33s -14? 16.3' 0.795 39.872 11.703 Up
Venus 21 55 33 -14 16.3 0.795 39.872 11.703 Up
fld01 = Venus
fld02 = 21
fld03 = 55
fld04 = 33
fld05 = -14
fld06 = 16.3
fld07 = 0.795
fld08 = 39.872
fld09 = 11.703
fld10 = Up
Moon 21h 17m 19s -15? 2.4' 62.4 ER 36.796 22.871 Up
Moon 21 17 19 -15 2.4 62.4 36.796 22.871 Up
fld01 = Moon
fld02 = 21
fld03 = 17
fld04 = 19
fld05 = -15
fld06 = 2.4
fld07 = 62.4
fld08 = 36.796
fld09 = 22.871
fld10 = Up
Mars 18h 11m 59s -24? 6.1' 2.431 4.552 56.184 Up
Mars 18 11 59 -24 6.1 2.431 4.552 56.184 Up
fld01 = Mars
fld02 = 18
fld03 = 11
fld04 = 59
fld05 = -24
fld06 = 6.1
fld07 = 2.431
fld08 = 4.552
fld09 = 56.184
fld10 = Up
Jupiter 20h 3m 35s -20? 49.4' 6.034 23.867 38.203 Up
Jupiter 20 3 35 -20 49.4 6.034 23.867 38.203 Up
fld01 = Jupiter
fld02 = 20
fld03 = 3
fld04 = 35
fld05 = -20
fld06 = 49.4
fld07 = 6.034
fld08 = 23.867
fld09 = 38.203
fld10 = Up
Saturn 11h 32m 59s +5? 8.6' 9.018 -47.333 157.471 Set
Saturn 11 32 59 +5 8.6 9.018 -47.333 157.471 Set
fld01 = Saturn
fld02 = 11
fld03 = 32
fld04 = 59
fld05 = +5
fld06 = 8.6
fld07 = 9.018
fld08 = -47.333
fld09 = 157.471
fld10 = Set
Uranus 23h 21m 30s -4? 57.9' 20.421 48.328 -18.527 Up
Uranus 23 21 30 -4 57.9 20.421 48.328 -18.527 Up
fld01 = Uranus
fld02 = 23
fld03 = 21
fld04 = 30
fld05 = -4
fld06 = 57.9
fld07 = 20.421
fld08 = 48.328
fld09 = -18.527
fld10 = Up
Neptune 21h 39m 30s -14? 22.8' 30.748 38.963 16.599 Up
Neptune 21 39 30 -14 22.8 30.748 38.963 16.599 Up
fld01 = Neptune
fld02 = 21
fld03 = 39
fld04 = 30
fld05 = -14
fld06 = 22.8
fld07 = 30.748
fld08 = 38.963
fld09 = 16.599
fld10 = Up
Pluto 18h 4m 34s -17? 44.5' 32.543 7.443 62.142 Up
Pluto 18 4 34 -17 44.5 32.543 7.443 62.142 Up
fld01 = Pluto
fld02 = 18
fld03 = 4
fld04 = 34
fld05 = -17
fld06 = 44.5
fld07 = 32.543
fld08 = 7.443
fld09 = 62.142
fld10 = Up