Re: REGEXP: only need last matching string
by inman (Curate) on Dec 23, 2005 at 12:05 UTC
|
$1 will contain the last match if you execute the regexp in list context.
(my $dum) = $str =~/abc\s(\d+)/g ;
print "dum is $1\n" ;
gives
dum is 14
| [reply] [d/l] [select] |
|
|
() = $str =~ /abc\s(\d+)/gs;
will suffice, i.e. no need for the $dum variable. | [reply] [d/l] [select] |
Re: REGEXP: only need last matching string
by prasadbabu (Prior) on Dec 23, 2005 at 12:16 UTC
|
#! /usr/bin/perl
$str = <<HERE ;
abc 10
abc 11
abc 12
abc 13
abc 14
HERE
($dum) = $str =~/abc\s(\d+)$/;
print "dum is $dum\n" ;
| [reply] [d/l] |
Re: REGEXP: only need last matching string
by salva (Canon) on Dec 23, 2005 at 12:05 UTC
|
($dum) = $str =~ /^.*abc\s(\d+)/s
though, I am not sure about the eficience of this regular expresion. | [reply] [d/l] |
|
|
When I read this, I thought "Don't be ridiculous! Yours is probably the most efficient method suggested!" Then I set about benchmarking the various suggestions to prove it. Alas, yours is only the second most efficient (in terms of time):
Rate inman blazar2 blazar1 jeanluca thedoe2 prasadbabu drmoron salva thedoe1
inman 107580/s -- -7% -28% -33% -51% -54% -72% -77% -78%
blazar2 115313/s 7% -- -23% -28% -48% -51% -70% -75% -76%
blazar1 149209/s 39% 29% -- -7% -32% -37% -61% -68% -69%
jeanluca 160157/s 49% 39% 7% -- -27% -32% -58% -65% -67%
thedoe2 220552/s 105% 91% 48% 38% -- -6% -43% -52% -54%
prasadbabu 235856/s 119% 105% 58% 47% 7% -- -39% -49% -51%
drmoron 384090/s 257% 233% 157% 140% 74% 63% -- -16% -20%
salva 459627/s 327% 299% 208% 187% 108% 95% 20% -- -5%
thedoe1 481345/s 347% 317% 223% 201% 118% 104% 25% 5% --
| [reply] [d/l] [select] |
|
|
I can see NO reason why thedoe1 should be performing any better than salva's code.
salva => sub { (my $dum) = $str =~ /^.*abc\s(\d+)/s; },
thedoe1 => sub { (my $dum) = $str =~ /(?<!abc).*abc\s(\d+)/gs; },
Those regexes are equivalent. In fact, I can't understand why in the world thedoe used a look-behind there. It accomplishes nothing, since the first place the regex tries to match is at the beginning of the string. The only difference that it could make is if pos($str) is something other than 0, and then that means it would not necessary operate properly (insofaras what was requested from the regex). Sorry to sound grumpy, but this is a misuse of a look-behind (and the /g modifier) that I think should be pointed out. There's no voodoo going on.
| [reply] [d/l] [select] |
|
|
well, you are benchmarking a corner case, that's when the last abc \d+ is at the end of the string.
When I said that I didn't know about its performance I was thinking on some not so convenient case, for instance, if the matching substr is near the beginning, in that case perl regexp engine is going to backtrack a lot and maybe looping with the OP regexp and discarding all but the last match could perform better.
| [reply] [d/l] |
Re: REGEXP: only need last matching string
by blazar (Canon) on Dec 23, 2005 at 12:22 UTC
|
(my $dum) = reverse $str =~/abc\s(\d+)/gs;
print "dum is $dum\n";
1 while $str =~/abc\s(\d+)/gs;
print "dum is $1\n";
| [reply] [d/l] |
Re: REGEXP: only need last matching string
by doctor_moron (Scribe) on Dec 23, 2005 at 12:31 UTC
|
#! /usr/bin/perl
$str = <<HERE ;
abc 10
abc 11
abc 12
abc 13
abc 14
HERE
($dum) = $str =~/\d+$/gs ;
print "dum is $dum\n" ;
does it work ?
zak
| [reply] [d/l] |
Re: REGEXP: only need last matching string
by thedoe (Monk) on Dec 23, 2005 at 14:26 UTC
|
You could use a negative look behind assertion to do this:
($dum) = $str =~/(?<!abc).*abc\s(\d+)/gs;
To read more about this feature, along with lots more on regex, check out perlre.
Update: Another way to do this is explained in Roy Johnson's post on look-ahead and look-behind. I knew I had seen this before, but couldn't find it when I was first answering your question.
/abc(?!.*abc)\s(\d+)/s
Not sure which is easiest for you to understand, but either way I would recommend reading that post. (Thanks to prasadbabu for linking to it in a later node so I could find it again!)
| [reply] [d/l] [select] |