Как я могу извлечь n-ное совпадение в регулярном выражении Perl? - PullRequest
1 голос
/ 31 марта 2010

Можно ли извлечь строку n th в строку слов в одинарных кавычках?

use strict;
use warnings;

my $string1 = "'I want to' 'extract the word' 'Perl','from this string'";
my $string2 = "'What about','getting','Perl','from','here','?'";

sub extract_quoted { 

    my ($string, $index) = @_;
    my ($wanted) = $string =~ /some_regex_using _$index/;
    return $wanted;
}

extract_wanted ($string1, 3); # Should return 'Perl', with quotes
extract_wanted ($string2, 3); # Should return 'Perl', with quotes

Ответы [ 7 ]

2 голосов
/ 31 марта 2010

Это должно сработать:

sub extract_quoted { 

    my ($string, $index) = @_;
    my $wanted = ($string =~ /'(.*?)'/g)[$index];
    return $wanted;
}
2 голосов
/ 31 марта 2010

Оператор match-g, вычисленный в контексте массива , выдает массив совпадений. Поэтому:

@matches = $string =~ /'(.*?)'/g;
$matches[$index-1];

- это один из способов получить то, что вы хотите.

2 голосов
/ 31 марта 2010
1 голос
/ 31 марта 2010

Вы можете попробовать:

sub extract_quoted {

        my ($string, $index) = @_;
        while($string =~ /'(.*?)'/g) {
                $index--;
                return $1 if(! $index); # return $1 if index became 0. 
        }
        return; # not found - returns undef or () depending on context.
}
0 голосов
/ 01 апреля 2010
sub extract_quoted {
        my ($string,$index) = @_;
        $c=1;
        @s = split /\'/,$string;
        for($i=1;$i<=$#s;$i+=2){
            $c==$index && return $s[$i];
            $c++;
        }
}
0 голосов
/ 31 марта 2010

Это может выглядеть уродливо, но

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
    : ();
}

бенчмаркинг предполагает, что это может стоить

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 },
}

Результаты:

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)
0 голосов
/ 31 марта 2010
use strict; use warnings;

use Text::ParseWords;

my $string1 = q{'I want to' 'extract the word' 'Perl','from this string'};
my $string2 = q{'What about', 'getting','Perl','from','here','?'};

print extract_wanted($_, 3), "\n" for ($string1, $string2);

sub extract_wanted {
    my ($string, $index) = @_;
    my $wanted = (parse_line '(:?\s|,)+', 0, $string)[$index - 1];
    return unless defined $wanted;
    return $wanted;
}

Выход:

Perl
Perl
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...