BryanK
BryanK

Reputation: 1221

Put regex match only into array, not entire line

I am trying to check each line of a document for a regex match. If the line has a match, I want to push the match only into an array.

In the code below, I thought that using the g operator at the end of the regex delimiters would make $lines value the regex match only. Instead $lines value is the entire line of the document containing the match...

my $line;
my @table;
while($line = <$input>){ 

    if($line =~ m/foo/g){

        push (@table, $line);

    }   


}
print @table;

If any one could help me get my matches into an array, it is much appreciated.

Thanks.

p.s. Still learning... so any explanations of concepts I may have missed is also much appreciated.

Upvotes: 1

Views: 627

Answers (3)

jkshah
jkshah

Reputation: 11703

g modifier in s///g is for global search and replace.

If you just want to push matching pattern into an array, you need to capture matching pattern enclosed by (). Captured elements are stored in variable $1, $2, etc..

Try following modification to your code:

my @table;
while(my $line = <$input>){ 
    if($line =~ m/(foo)/){
        push (@table, $1);
    }   
}
print @table;

Refer to this documentation for more details.


Or if you want to avoid needless use of global variables,

my @table;
while(my $line = <$input>){ 
    if(my @captures = $line =~ m/(foo)/){
        push @table, @captures;
    }   
}

which simplifies to

my @table;
while(my $line = <$input>){ 
    push @table, $line =~ m/(foo)/;
}

Upvotes: 6

Gaurav Pant
Gaurav Pant

Reputation: 4199

If you file is not very big(100-500mb fine for 2 GB RAM) then you can use below.Here I am extracting numbers if matched in line.It will be much faster than the foreach loop.

#!/usr/bin/perl
open my $file_h,"<abc" or die "ERROR-$!";
my @file = <$file_h>;
my $file_cont = join(' ',@file);
@file =();
my @match = $file_cont =~ /\d+/g;
print "@match";

Upvotes: 0

edibleEnergy
edibleEnergy

Reputation: 1849

Expanding on jkshah's answer a little, I'm explicitly storing the matches in @matches instead of using the magic variable $1 which I find a little harder to read. "__DATA__" is a simple way to store lines in a filehandle in a perl source file.

use strict;
use warnings;
my @table;
while(my $line = <DATA>){
    my @matches = $line =~ m/(foo)/;
    if(@matches) {
        warn "found: " . join(',', @matches );
        push(@table,@matches);
    }
}
print @table;

__DATA__
herp de derp foo
yerp fool foo flerp
heyhey

Upvotes: 1

Related Questions