Как получить последовательные пары слов в Perl

#perl #split

#perl #разделение

Вопрос:

С помощью этого предложения:

 my $sent = "Mapping and quantifying mammalian transcriptomes RNA-Seq";
  

Мы хотим получить все возможные последовательные пары слов.

 my $var = ['Mapping and',
           'and quantifying',
           'quantifying mammalian',
           'mammalian transcriptomes',
           'transcriptomes RNA-Seq'];
  

Есть ли компактный способ сделать это?

Комментарии:

1. Ответы различаются тем, сохраняют ли они исходный пробел между словами или просто используют пробел. Что вы хотели?

Ответ №1:

ДА.

 my $sent = "Mapping and quantifying mammalian transcriptomes RNA-Seq";
my @pairs = $sent =~ /(?=(S s S ))S /g;
  

Ответ №2:

Вариант, который (возможно, неразумно) зависит от порядка вычисления оператора, но не зависит от причудливых регулярных выражений или индексов:

 my @words = split /s /, $sent;
my $last = shift @words;
my @var;
push @var, $last . ' ' . ($last = $_) for @words;
  

Ответ №3:

Это работает:

 my @sent = split(/s /, $sent);
my @var = map { $sent[$_] . ' ' . $sent[$_   1] } 0 .. $#sent - 1;
  

т. е. просто разделите исходную строку на массив слов, а затем используйте map для итеративного получения желаемых пар.

Ответ №4:

У меня это не в виде одной строки, но следующий код должен подсказать вам, с чего начать. В основном делает это с помощью push , а regext с помощью /g .

 #!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;
$Data::Dumper::Indent = 1;

my $t1 = 'aa bb cc dd ee ff';
my $t2 = 'aa bb cc dd ee';

foreach my $txt ( $t1, $t2 )
{
    my @a;
    push( @a, $amp; ) while( $txt =~ /GS (s S |)s*/g );
    print Dumper( @a );
}
  

Одна строка благодаря синтаксису от @ysth

  my @a = $txt =~ /G(S (?:s S |))s*/g;
  

Мое регулярное выражение немного отличается тем, что если у вас нечетное количество слов, последнее слово все равно получает запись.