tags:

views:

244

answers:

3

The following is the data I am working on:

__DATA__

Node 1: 

        98 debug : fill 100 
       102 debug : fill 104
Node 2:

        88 debug : fill 120 
       152 debug : fill 164

I want to write a regex/(or whatever is appropriate) to capture information from data below Node 1, say '98 : 100', but only after identification of Node 1 and store it in an array say @value1 (i.e.values in @value1 correspond to data below Node 1). And similarly capture and store information from data below node 2, say 152 : 164, after node 2 has been identified in a different array say '@value2'. The regex I am using to capture information is "qr/\s+([0-9]{2,3})\s[a-z]+\s(:)\s[a-z]\s([0-9]{3})/ ". But, if I use an 'if' statement

    while (<>){
     if ($_=~ /Node 1/){
     #capture information using regex
     }
    }

before regex, script doesn't return any value probably because it searches or regex in same line after word "Node".

Any suggestions on how to jump to the next line after identification of particular node and capture information using regex.

+1  A: 

Edit: Although accurate, this answer misses a large part of the question.


Use next to go to the next iteration of the loop; use last to leave the loop. If you have labelled (nested) loops, you can use next LABEL; to jump to the next iteration of the named loop, etc.

Compare continue and break in C and similar languages.

Jonathan Leffler
+5  A: 

Your question is a little confusing. You seem to want to use symbolic references, but you would be better off using a hash. See also "Why it's stupid to use a variable as a variable name" parts 1, 2 and 3.

#!/usr/bin/perl

use strict;
use warnings;

my %data;

my $current_node;

while ( <DATA> ) {
    /^Node ([0-9]+):/ and $current_node = $1 and next;
    if ( /^\s+ ([0-9]+) \s debug \s : \s fill \s ([0-9]+)/x ) {
        push @{ $data{"value$current_node"} }, "$1 : $2";
    }
}

use Data::Dumper;
print Dumper \%data;

__DATA__

Node 1:

        98 debug : fill 100
       102 debug : fill 104
Node 2:

        88 debug : fill 120
       152 debug : fill 164
Sinan Ünür
+1 for the URLs to Mark-Jason Dominus's trilogy (and for being a decent answer to the question).
Jonathan Leffler
($current_node) = /^Node ([0-9]+):/ and next; (unless you are blessed with cow orkers who would just go and remove the "extra" parens.)
ysth
@ysth Actually, there would introduce an annoying bug here.
Sinan Ünür
+3  A: 

You could also parse one Node at a time into a hash like this:

local $/ = "\nNode ";

while ( <DATA> ) {
    chomp; s/^Node //;  # remove 1st Node header
    my ($current_node) = /^(\d+):/;
    map {
        if (/^\s+ ([0-9]+) \s debug \s : \s fill \s ([0-9]+)/xm ) {  # borrowed from Sinan
           push @{ $data{"value$current_node"} }, "$1 : $2";
       }
    } split /\n/;
}

It's more useful in cases where the [Node] record delimiter is a constant string and $current_node may be buried somewhere in the record itself.

bubaker