Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Dealing with formatted array

Status
Not open for further replies.

jriggs420

Programmer
Sep 30, 2005
116
US
Hi All-
I have the following code which is pretty straight forward, for getting data into a form the 'real' script can use.

Code:
     7 while ($ln=<DATA>){if ($ln!~ /^\s*$/){
      8         $ln=~ s/(^[1-9])/\n$1/g;
      9         push @goodat , $ln;}
}
This output looks as it should when I print out by itself. I'm having a problem running the second part
Code:
    33 foreach $ln (@goodat) { do sth;}
Seems like this part of the script is ignoring the newlines I have just inserted, which are crucial. Any ideas why this may be? What can I do to ensure the second half 'sees' the newlines I have put in? TIA,

Joe

Because a thing seems difficult for you, do not think it impossible for anyone to accomplish.
Marcus Aurelius
 
I'm confused.
Code:
$ln=~ s/(^[1-9])/\n$1/g;
will only change the data at the start of the line, because of the caret. So the g modifier is pointless. Maybe you could post a sample of the 'before' and 'after' data so we can see what you want to do?

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
You're correct Steve, the 'g' is in fact, pointless, I hadn't noticed that, but it still achieves the desired output. Basically, I need to clean up the data before I can process it. In data could look like this:
Code:
___INDATA______
1. qqqq

www
eee
2. wwww
rrr

rrr
___OUTDATA___

1. qqqq
www
eee

2. wwww
rrr
rrr
Then I have some if/elsif/etc conditions depending on the line (blank/leading num/text only) to perform specific tasks. The problem I'm having is the 2nd part of the script isn't recognizing the blank lines i.e. the '\n' when I perform a 'foreach' on the array I have created.
If I simply print the formatted (ln 7,8,9) array, it looks as it should, so I am confused why the 2nd half is not recognizing those lines. Here's the shell of it:
Code:
my @array;
my $start_regex = "^[1-9]"; # 
my $end_regex   = "^s*\$";   #
foreach $ln (@goodat) { 
    if ( @array and $ln =~ $end_regex ) {
        do_something_to(@array);
        undef @array;
    }
    elsif ( @array ) {
        # filling array
        push @array, $ln;
    }
    elsif ( $ln =~ $start_regex and !eof DATA) {
        # begin filling up the array!
        push @array, $ln;  
    }
    else {
        # we haven't gotten a 'start',
    }
} #_ while{}

# deal with the possibility that we 'started' but didn't 'end'
if (@array) { warn 'Start with out end at EOF!' }
Any Ideas, please excuse any typos <-_->

Because a thing seems difficult for you, do not think it impossible for anyone to accomplish.
Marcus Aurelius
 
should you be using delimiters here:

Code:
if ( @array and $ln =~ /$end_regex/ ) {

why are the patterns written as variables instead of directly into the regexp:

Code:
if ( @array and $ln =~ /^s*$/; ) {
 
Is that a good representation of your data? My first guess is no, but you might be able to adapt this to what you need:
Code:
foreach (<DATA>) {
    next if /^\s*$/; # Skip output if the line is blank;
    chomp;
    if (/^\s*\d+\s*\./) {
        # Starts with optional spaces, any number of digits
        # Optional spaces and a . character
        print "\n", $_, "\n";
    } elsif (/^\s*\w+\s*$/) {
        # Beggining of line, optional spaces, word characters
        # optional spaces and end of line
        print $_, "\n";
    } else {
        die "Did not match input line $.\nText: $_\n";
    }
}

__DATA__
1. qqqq

www
eee
2. wwww
rrr

rrr
Which produces the output:
Code:
1. qqqq
www
eee

2. wwww
rrr
rrr
 
Sorry it took so long to get back. As I was reading through this thread again, I realized we weren't really addressing the issue I was have the *most* problems with. I'll try to detail it out again.

I have two separate programs. One formats the input data, into a temporary file. The second goes into that temporary file and parses the data no problem. Naturally, I want to combine these two into one. When I put the exact same code from the 1st into the 2nd, it seems like the format changes aren't being recognized. Just to double check, I funneled the formatted data into a test file as well and verified the correct changes had been made. I've tried putting the formatted data into an array and also into a tmp file. Both fail the 2nd part of the script. The code I posted above is the 'guts' of it, except my 'end_regex' is '$\n' (!EOF is superfluous in a foreach loop)
 
part of the problem could be here:

Code:
my $end_regex   = "^s*\$";   #


you probably wanted to write that as:

Code:
my $end_regex   = "^\s*$";   #

 
OK, let's take a step back. Parse the file into a data structure (in this case, a hash of arrays). Once it's in there you can iterate over it however you want, including printing it out in the original intermediate file format. You don't need to have if statements that look for newlines embedded in your arrays.
Code:
use strict;
use warnings;
use Data::Dumper;

my (%data, $key);

while (<DATA>) {
	chomp;
	if (/^\s*(\d+)\.\s*(.*)$/) {
		$key = $1;
		push @{$data{$key}}, $2;
		next;
	}
	push @{$data{$key}}, $_ if ($key and /^\s*\w+/);
}

print Dumper(%data); # data structure

foreach (sort {$a <=> $b} keys %data) {
	print "$_. @{$data{$_}}[0]\n", join("\n", @{$data{$_}}[1, -1], "\n\n");
}
 
__DATA__
1. qqqq

www
eee
2. wwww
rrr

rrr

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top