How can I extract the nth occurrence of a match in a Perl regex?

后端 未结 7 865
执笔经年
执笔经年 2020-12-22 01:32

Is it possible to extract the nth match in a string of single-quoted words?

use strict;
use warnings;

my $string1 = \"\'I want to\' \'ex         


        
7条回答
  •  别那么骄傲
    2020-12-22 02:03

    It may look ugly, but

    my $quoted = qr/'[^']+'/;  # ' fix Stackoverflow highlighting
    my %_extract_wanted_cache;
    sub extract_wanted_memo { 
      my($string, $index) = @_;
      $string =~ ($_extract_wanted_cache{$index} ||=
                    qr/^(?:.*?$quoted.*?){@{[$index-1]}}($quoted)/)
        ? $1
        : ();
    }
    

    benchmarking suggests it might be worthwhile:

    sub extract_wanted { 
      my($string, $index) = @_;
      $string =~ /^(?:.*?$quoted.*?){@{[$index-1]}}($quoted)/
        ? $1
        : ();
    }
    
    sub extract_wanted_gindex {
      my($string, $index) = @_;
      ($string =~ /$quoted/g)[$index-1];
    }
    
    use Benchmark;
    timethese -1 => {
      nocache => sub { extract_wanted        $string2, 3 },
      memoize => sub { extract_wanted_memo   $string2, 3 },
      index   => sub { extract_wanted_gindex $string2, 3 },
    
      nocache_fail => sub { extract_wanted        $string2, 100 },
      memoize_fail => sub { extract_wanted_memo   $string2, 100 },
      index_fail   => sub { extract_wanted_gindex $string2, 100 },
    }
    

    Results:

    Benchmark: 
    running
     index, index_fail, memoize, memoize_fail, nocache, nocache_fail
     for at least 1 CPU seconds
    ...
    
         index:   1 w/c secs (1.04 usr + 0.00 sys = 1.04 CPU) @183794.23/s (n=191146)
    index_fail:   1 w/c secs (1.03 usr + 0.00 sys = 1.03 CPU) @185578.64/s (n=191146)
       memoize:   1 w/c secs (1.00 usr + 0.00 sys = 1.00 CPU) @264664.00/s (n=264664)
    memoize_fail: 0 w/c secs (1.03 usr + 0.00 sys = 1.03 CPU) @835106.80/s (n=860160)
       nocache:   0 w/c secs (1.03 usr + 0.00 sys = 1.03 CPU) @196495.15/s (n=202390)
    nocache_fail: 2 w/c secs (1.03 usr + 0.00 sys = 1.03 CPU) @445390.29/s (n=458752)

提交回复
热议问题