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

Fellow Monks, I come to you with a question that I have already solved my way with my current knowledge.

However, I find the solution(s) slightly unperlish and thought I would get some feedback from you.

Basically I found that the index function does not DWIM in array context, like for example my @offset = index($txt, $srch);

Below are two variations I came up with that works to large extent, I think.

#!perl -w use strict; my $txt = 'Trying! to get! index functionality! in array context!?'; my $srch = '!'; my @offset; my $l = -1; @offset = map {$l += length($_) + 1 } $txt =~ /(.*?)(?:$srch)/g; print "RegExp: ", join(", ", @offset), "\n"; @offset =(); my $ofs = 0; while( ($ofs = index($txt, $srch, $ofs)) > 0 ) { push @offset, $ofs++; } print "Index : ", join(", ", @offset), "\n";
As you can see I would like it to work under strict, preferably be a "one-liner" and not require additional/temporary variables.

TIA
---
It's unfair to be an expert.

Replies are listed 'Best First'.
Re: 'Trying! to get! index functionality! in array context!?'
by Kanji (Parson) on Jan 28, 2002 at 15:55 UTC

    You can use pos() in combination with m//g ...

    while ( $txt =~ /$srch/g ) { push @offset, pos($txt) - 1; }

    ... or as one-liners ...

    push @offset, pos($txt) - 1 while $txt =~ /$srch/g; # while ( $txt =~ /$srch/g ) { push @offset, pos($txt) - 1 }

        --k.


      Quote the meta my friend, quote the meta, even if you don't use quotemeta ;D
      $>perl -le"$srch='?';$txt='?i?a?b?adfads?';print pos($txt) - 1 while $ +txt =~ / \Q$srch\E/g;" 0 2 4 6 13
Bones! Take a reading . . .
by Fletch (Bishop) on Jan 28, 2002 at 20:22 UTC

    This actually uses index, so it should run faster than regex based versions. Benchmarking is left as an exercise for the more interested. :)

    sub index_a { my( $txt, $search ) = @_; my @ret; my $ind = 0; my $cur = 0; while( ($cur = index( $txt, $search, $ind )) != -1 ) { push @ret, $cur; $ind = $cur + 1; } return @ret; }
      This actually uses index, so it should run faster than regex based versions.
      Not necessarily. If the text is a simple string, the regex engine can kick in BoyerMoore and other optimizations, and actually beat a naive index operation. Having said that, I believe that modern Perls actually hand index to the regex engine, just so that it can use BoyerMoore!

      -- Randal L. Schwartz, Perl hacker