AnonGeek
AnonGeek

Reputation: 7938

Perl Regex - Get offset as line number instead of character position in case of a MATCH

I am reading a complete file in a string and then doing a regex match as below:

if($str =~ m/$regex/gc) {
     $offset = $+[0];
}

Using this code, I can capture the position where the last successful match ends.

Now this will give the position as character number.

Is there any way that I can get offset as line number?

What I am doing for now is that I am counting the number of newline characters from beginning of $str upto end $offset.

I want to know is there a direct way to capture line number for a regex match.

Upvotes: 2

Views: 1095

Answers (2)

Nahuel Fouilleul
Nahuel Fouilleul

Reputation: 19315

see perldoc perlvar, special variable $.

EDIT: after comment, sorry I read too fast

another solution, if there is many matches, could be to create an array which contains offset of new lines: $a[0]-> offset of line 2, etc. then to approximate the line number and finally increase or decrease to find the line. May have a problem if the last line does not contain a newline character.

# create an array with offset of new lines
@a=(0,0);push@a,$-[0]while$str=~/\n/gc;

if($str =~ m/$regex/gc) {
  $offset = $+[0]; 
  # get an approximation of line
  $l=int$offset*@a/$a[-1];
  # increment or decrement
  $l++while$a[$l+1]<$offset;
  $l--while$a[$l]>$offset;
}

EDIT: not tested, changes initialize @a=(0,0) to avoid +2 at the end and safe if match on first line $l++while$a[$l+1]$offset and *@a added

Upvotes: 1

Zaid
Zaid

Reputation: 37136

Contrary to what one might imagine, Nahuel's suggestion of using $. is actually doable in this case.

This is because one can read from strings just like files using Perl:

use strict;
use warnings;

my $str = <<EOS;
spam
spam
spam
match
spam
match
EOS

open my $handle, '<', \$str or die $!;

while ( <$handle> ) {

    print $., "\n" if /match/;
}

OUTPUT

4
6

Upvotes: 4

Related Questions