http://www.perlmonks.org?node_id=993899

Thomas Kennll has asked for the wisdom of the Perl Monks concerning the following question:

I want to find a matching pattern field number/col number of a string.. For eg, if i have my code as below. Can someone help me to find the column number of a matching pattern.. my $data = "Region Item volume Month" if ($data1 =~ /Item | volume/) { print "column number of item and volume"; } I want to print the column number as 1 and 2
  • Comment on finding the field number of a matching pattern in perl

Replies are listed 'Best First'.
Re: finding the field number of a matching pattern in perl
by Anonymous Monk on Sep 16, 2012 at 08:43 UTC
      • #!/usr/bin/perl -- use strict; use warnings; my $data = "Region Item volume Month"; my @da = split /\s+/, $data; for my $daix ( 0 .. $#da ){ $_ = $da[$daix]; /volume/ and print "volume $daix\n"; /Item/ and print "Item $daix\n"; /(volume|Item)/ and print "$1 $daix\n"; } __END__
      • #!/usr/bin/perl -- use strict; use warnings; my $data = "Region Item volume Month"; my @da = split /\s+/, $data; my $daix = 0; for( @da ){ /volume/ and print "volume $daix\n"; /Item/ and print "Item $daix\n"; /(volume|Item)/ and print "$1 $daix\n"; $daix++; } __END__
      • #!/usr/bin/perl -- use strict; use warnings; use 5.012; my $data = "Region Item volume Month"; my @da = split /\s+/, $data; while( my($daix, $_) = each @da ){ /volume/ and print "volume $daix\n"; /Item/ and print "Item $daix\n"; /(volume|Item)/ and print "$1 $daix\n"; } __END__
Re: finding the field number of a matching pattern in perl
by ww (Archbishop) on Sep 16, 2012 at 12:02 UTC
    You can make it easier to help by sharing some additional info:
    1. What is the source format of your data; a database, an html table, a doc table, a spreadsheet, a csv file?
    2. How are you making the data available to perl; slurping a file; reading line by line, db Row by Row or field by field?

    Your my $data = "Region Item volume Month" if ($data1= .... makes me think you're trying to step thru an array where the elements (scalars) $data0,$data1, $data2 (etc) each contain the items you want and two more... (in which case the array after "my" needs an @ sigil rather than $). If that's in fact the case, have you mastered moving the data from its source to your script? And if so, then a for loop;split and (since your regex is borked, as noted above) perlretut should help.

    What you've provided (as of this writing) just isn't enough to be sure these suggestions are on track. So please update your question (and mark the update ). And even pseudo-code benefits from using required elements like semi-colons.

Re: finding the field number of a matching pattern in perl
by roboticus (Chancellor) on Sep 16, 2012 at 14:16 UTC

    Thomas Kennll:

    You've got plenty of answers already, so I'll just play around a little:

    $ cat u.pl my $data = "Region Item volume Month"; my %h = do {my $cnt=0; map {$_=>++$cnt} split /\s+/, $data}; print "$_ $h{$_}\n" for grep {exists $h{$_}} qw(Item volume Tuba); $ perl u.pl Item 2 volume 3

    The hash maps the fields with the field index. Wrapping the right hand side of the hash assignment in a do statement lets me localize a temporary variable. Preincrementing the temp variable converts the field numbers to one-based numbering.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: finding the field number of a matching pattern in perl
by remiah (Hermit) on Sep 16, 2012 at 12:06 UTC

    anonymous's split : the better ones. mine ... not so good.

    use strict; use warnings; use Data::Dumper; use 5.010; my $data = "Region day Item volume Month district piece amount day ... + one more test"; print "$data\n"; my (@sep); push @sep, 0; push @sep, $-[0] while( $data =~ /\s+/g ); push @sep, length($data); while( $data =~ /Item|volume|day|test/g ){ #printf "%s|%s|%s,matched pos=%s\n", $`,$&,$',$-[0]; my $match_bgn = $-[0]; for( my $idx=0 ; $idx < $#sep; $idx ++){ # printf "match pos=%d, %d .. %d\n" #,$match_bgn ,$sep[$idx] ,$sep[$idx+1]; if( $match_bgn > $sep[$idx] && $match_bgn < $sep[$idx+1]) { print "col of $&=$idx\n"; } } } __DATA__ Region day Item volume Month district piece amount day ... one more te +st col of day=1 col of Item=2 col of volume=3 col of day=8 col of test=12