unkaitha
unkaitha

Reputation: 225

REGEX matching and extraction

I have a file consisting of many set of values. I am trying to just extract the required lines that matched in a file once a REGEX is found. File.txt

    ...... 
    ......
    TRIP (
            ?name           "model"
            ?prompt         "Model name"
            ?defamount       "USD100"
            ?type           "adventure"
            ?display        "no"
            ?photos       "800"
               )
    TRIP (
            ?name           "macro"
            ?prompt         "macro model name"
            ?defamount       "USD500"
            ?type           "adventure"
            ?display        "no"
            ?photos       "1200"
            )
      TRIP( 
            ?name           "description"
            ?prompt         "description"
            ?defamount       "USD400"
            ?type           "historical"
            ?display        "yes"
            ?photos       "900"
             )
            .......
........
.....
.......
......

I want to extract the line with "name and model" then "name and description" along with these line i want to extract the 1st "defamount" once the the line with "name and model" then "name and description" are matched. I tried with loops but i wasnt succesful

use strict;
open FILE, "<File.txt";
open FILE2, ">>data1.l";

while (my $string = <FILE>) {

    if ($string =~ m/^ CELL/ig) {

        print FILE2 $string;
    }
    elsif ($string =~ m/"model"/i) {

        print FILE2 $string;
    }
    elsif ($string =~ m/defamount/o) {

        print FILE2 $string;
    }
    elsif($string =~ m/"description"/i) {

        print FILE2 $string;
    }
    elsif($string =~ m/defamount/o) {

        print FILE2 $string;
    }
}
close FILE;
close FILE2; 

This gives me all the "defamount" lines from the file, but i want just the 1st defamount after the matching the above mentioned regex

Upvotes: 0

Views: 100

Answers (1)

RET
RET

Reputation: 9188

Each of those if...elsif constructions are calculated on every line of the input. You need to treat them as groups of lines, and hence keep track of whether you've already matched a line to decide if this is a group you want to keep or not.

Without completely rewriting your program, you need to do something like this:

my $keep = 0;

while(my $string = <FILE>){
    if ($string =~ m/name\s+/){ #matches name, start of new group
        if ($string =~ m/"(model|description)"/){ # keep this group
            $keep = 1;
            print FILE2 $string;
        } else { #discard this group
            $keep = 0;
        }
    }
    if ($string =~ m/defamount/ && $keep){ #only print if in a 'keep' block
        print FILE2 $string;
    }
}

To be honest, I would write this quite differently if I was starting from scratch. That's some pretty agricultural perl you've got going on there. But hopefully the logic of what I've written will help you get going.

Upvotes: 1

Related Questions