kenny.g
kenny.g

Reputation: 19

How to match the first line and store regex match in the subsequent lines in perl?

I have a header file which i would want extract some of the variables out using regex in perl.

Below is a part of the header file:

banana.h

/******************************************************************************/
//  BANANA               = 1,
/******************************************************************************/
#define BANANA_FAMILY_GREEN         0x01
#define BANANA_FAMILY_YELLOW        0x02
#define BANANA_FAMILY_SPECIAL       0x03

#define BANANA_MAJOR_VER_SWEET      0x01
#define BANANA_MAJOR_VER_BITTER     0x02

#define BANANA_MINOR_VER_BIG      0x01
#define BANANA_MINOR_VER_SMALL     0x02
/******************************************************************************/
//  POTATO               = 2,
/******************************************************************************/
.
.
.

Let's say I want to match "BANANA = 1, " and also " / **********************************************/ " to find the pattern below it with pattern "#define " and extract the "BANANA_FAMLY_GREEN 0x01" and so on.

Below is the regex pattern i am using:

if ($banana_header =~ m/.*\s*BANANA\s*\=\s*\d+\s*.+/)
{
    next;
    if ($banana_header =~ m/#define\s*(\w+)\s*0x(\d+)\s*/)
    {
        print "word:$1\n";
        print "digit:$2\n";
    }
}

But i can't seem to get into the methods of the second if-conditions, are there something that i am missing here? i have tried using modifier /s and match newline with . but that can't seem to work either.

Upvotes: 0

Views: 163

Answers (2)

John Morris
John Morris

Reputation: 721

As @choroba mentions the next; makes the rest unreachable. Besides that the second if statement wouldn't be reached anyway since the next round would contain the next line, and so your code that prints the match still wouldn't be reached. I am not sure how you are populating $banana_header, but assuming you are reading from STDIN, this should work:

$fruit_flag=0;
while(<STDIN>)
{
    chomp;
    $banana_header=$_;
    if ($fruit_flag == 0 && $banana_header =~ m/.*\s*BANANA\s*\=\s*\d+\s*.+/)
    {
        $fruit_flag=1;
        next;
    }

    if ($fruit_flag)
    {
        if ($banana_header =~ m/#define\s*(\w+)\s*0x(\d+)\s*/)
        {
            print "word:$1\n";
            print "digit:$2\n";
        }
        elsif ($banana_header =~ m/\/\//)
        {
            $fruit_flag=0;
        }
    }
}

Upvotes: 1

Gilles Qu&#233;not
Gilles Qu&#233;not

Reputation: 185025

Try doing this :

BEGIN { $/ = "\000"; $\ = undef; }
while (defined($_ = <ARGV>)) {
    print $1, $2 if /\b(BANANA\s*\=\s*\d+),\s*\n.*\n#define(.*)/;
}

Upvotes: 0

Related Questions