Perl函数,用于使用开始、结束和步骤对字符串进行切片

Perl函数,用于使用开始、结束和步骤对字符串进行切片,perl,Perl,我想使用start、end和step分割字符串。假设起点坐标为1,终点坐标为22,步长为3。切片字符串应仅选择坐标1、4、7、10、13、16、19、22中的元素。我已经编写了一个函数get_subseq来实现这一点。在Perl中有没有一种更短的方法来实现这一点 sub get_subseq { my ( $seq, $start, $end, $step ) = @_; my $index = $start; while ( $index <= $end ) {

我想使用start、end和step分割字符串。假设起点坐标为1,终点坐标为22,步长为3。切片字符串应仅选择坐标1、4、7、10、13、16、19、22中的元素。我已经编写了一个函数get_subseq来实现这一点。在Perl中有没有一种更短的方法来实现这一点

sub get_subseq {
    my ( $seq, $start, $end, $step ) = @_;
    my $index = $start;
    while ( $index <= $end ) {
        print substr $seq, $index, 1;
        $index += $step;
    }
}

my $sequence = 'AGGGTAGAGTGAGAAGCACCAGCAGGCAGTAACAGC';

# The result should be GTAGACCC
get_subseq( $sequence, 1, 22, 3 );

一种方法是:生成索引列表,然后使用map获取相应的字符

合并成一份声明

use warnings;
use strict;
use feature 'say';

my $seq = q(AGGGTAGAGTGAGAAGCACCAGCAGGCAGTAACAGC); 

my ($beg, $end, $step) = (1, 22, 3); 

my @subseq = 
    map { substr $seq, $_, 1 } 
    grep { ($_-$beg) % $step == 0 } 
    $beg..$end; 

say "@subseq";
这可以在$beg..$end范围内折叠成一个迭代

如果结果需要一个字符串,请按空字符串加入列表

当然,还有一些库,它们可以快速生成一个范围。有这样一个范围函数,同时它也有一系列有趣的算法

use List::Gen qw(range);

my @ss = map { substr $seq, $_, 1 } @{ range $beg, $end, $step };

say "@ss";
它的范围返回一个生成器,它具有有趣的属性。取消对它的引用将生成值列表。见文件

虽然这些语句只返回一个语句的结果,因此较短,但我喜欢您自己的sub,它非常清晰,在许多情况下可能更有效

它可以简化一点更罕见的!C样式for循环的使用


您可以使用任何方法获取@索引,这些索引不需要是数组,但可以是通过上面使用的任何方法生成的列表。这两种方法中哪一种更有效完全取决于细节——序列的长度、到样本的索引范围的长度、它们之间的关系、步长。

一种方法:生成索引列表,然后使用map获取相应的字符

合并成一份声明

use warnings;
use strict;
use feature 'say';

my $seq = q(AGGGTAGAGTGAGAAGCACCAGCAGGCAGTAACAGC); 

my ($beg, $end, $step) = (1, 22, 3); 

my @subseq = 
    map { substr $seq, $_, 1 } 
    grep { ($_-$beg) % $step == 0 } 
    $beg..$end; 

say "@subseq";
这可以在$beg..$end范围内折叠成一个迭代

如果结果需要一个字符串,请按空字符串加入列表

当然,还有一些库,它们可以快速生成一个范围。有这样一个范围函数,同时它也有一系列有趣的算法

use List::Gen qw(range);

my @ss = map { substr $seq, $_, 1 } @{ range $beg, $end, $step };

say "@ss";
它的范围返回一个生成器,它具有有趣的属性。取消对它的引用将生成值列表。见文件

虽然这些语句只返回一个语句的结果,因此较短,但我喜欢您自己的sub,它非常清晰,在许多情况下可能更有效

它可以简化一点更罕见的!C样式for循环的使用


您可以使用任何方法获取@索引,这些索引不需要是数组,但可以是通过上面使用的任何方法生成的列表。这两种方法中哪一种更有效完全取决于细节——序列的长度、到样本的索引范围的长度、它们之间的关系、步长。

可以通过在感兴趣的位置提取字符来找到解决方案

步骤1:生成索引数组

步骤2:将$seq拆分为数组

步骤3:选择$seq数组索引位置的字符

步骤4:连接结果字符

步骤5:输出结果

它比多次使用substr快得多

use strict;
use warnings;
use feature 'say';

my $seq = 'AGGGTAGAGTGAGAAGCACCAGCAGGCAGTAACAGC';
my($pos,$end,$inc) = (1,22,3);
my @index;

for(;$pos<=$end;$pos+=$inc) { push @index, $pos; }

say join('',(split('',$seq))[@index]);

可以通过在感兴趣的位置提取字符来找到解决方案

步骤1:生成索引数组

步骤2:将$seq拆分为数组

步骤3:选择$seq数组索引位置的字符

步骤4:连接结果字符

步骤5:输出结果

它比多次使用substr快得多

use strict;
use warnings;
use feature 'say';

my $seq = 'AGGGTAGAGTGAGAAGCACCAGCAGGCAGTAACAGC';
my($pos,$end,$inc) = (1,22,3);
my @index;

for(;$pos<=$end;$pos+=$inc) { push @index, $pos; }

say join('',(split('',$seq))[@index]);

没有人喜欢使用正则表达式

join'',substr($seq,$start,$end-$start+1)=~/(?=(.)).{0,$step}/gs
这演示了如何使用正则表达式匹配来处理这类事情,有时候比循环或拆分和切片更有效。一个更有趣但效率不高的方法是避开substr:

join '',$seq=~/(?<=.{$start})(?<!..{$end})(?=(.)).{0,$step}/gs

没有人喜欢使用正则表达式

join'',substr($seq,$start,$end-$start+1)=~/(?=(.)).{0,$step}/gs
这演示了如何使用正则表达式匹配来处理这类事情,有时候比循环或拆分和切片更有效。一个更有趣但效率不高的方法是避开substr:

join '',$seq=~/(?<=.{$start})(?<!..{$end})(?=(.)).{0,$step}/gs

是的,特别是这个:@zdim为你的娱乐添加了一个替代方案我是的,特别是这个:@zdim为你的娱乐添加了一个替代方案