Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 为什么将此语句视为字符串而不是其结果?_Regex_Perl_String - Fatal编程技术网

Regex 为什么将此语句视为字符串而不是其结果?

Regex 为什么将此语句视为字符串而不是其结果?,regex,perl,string,Regex,Perl,String,我正在尝试对大量字符串(蛋白质序列)进行基于合成的过滤。 为了解决这个问题,我编写了一组三个子例程,但我在两个方面遇到了麻烦——一个小调,一个大调。小问题是,当我使用时,我会收到关于只使用$a和$b一次的警告,并且这些警告未初始化。但是我相信我正确地调用了这个方法(基于CPAN对它的输入和来自web的一些示例)。 主要问题是一个错误“当使用“strict refs”时,不能使用字符串(“17/32”)作为散列引用…” 似乎只有当&comp中的foreach循环将哈希值作为字符串而不是计算除法运算

我正在尝试对大量字符串(蛋白质序列)进行基于合成的过滤。
为了解决这个问题,我编写了一组三个子例程,但我在两个方面遇到了麻烦——一个小调,一个大调。小问题是,当我使用时,我会收到关于只使用
$a
$b
一次的警告,并且这些警告未初始化。但是我相信我正确地调用了这个方法(基于CPAN对它的输入和来自web的一些示例)。
主要问题是一个错误
“当使用“strict refs”时,不能使用字符串(“17/32”)作为散列引用…”

似乎只有当
&comp
中的
foreach
循环将哈希值作为字符串而不是计算除法运算时,才会发生这种情况。我肯定我犯了一个新手错误,但在网上找不到答案。我第一次看perl代码是在上周三

use List::Util;
use List::MoreUtils;
my @alphabet = (
 'A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I',
 'L', 'K', 'M', 'F', 'P', 'S', 'T', 'W', 'Y', 'V'
);
my $gapchr = '-';
# Takes a sequence and returns letter => occurrence count pairs as hash.
sub getcounts {
 my %counts = ();
 foreach my $chr (@alphabet) {
  $counts{$chr} = ( $_[0] =~ tr/$chr/$chr/ );
 }
 $counts{'gap'} = ( $_[0] =~ tr/$gapchr/$gapchr/ );
 return %counts;
}

# Takes a sequence and returns letter => fractional composition pairs as a hash.
sub comp {
 my %comp = getcounts( $_[0] );
 foreach my $chr (@alphabet) {
  $comp{$chr} = $comp{$chr} / ( length( $_[0] ) - $comp{'gap'} );
 }
 return %comp;
}

# Takes two sequences and returns a measure of the composition difference between them, as a scalar.
# Originally all on one line but it was unreadable.

sub dcomp {
 my @dcomp = pairwise { $a - $b } @{ values( %{ comp( $_[0] ) } ) }, @{ values( %{ comp( $_[1] ) } ) };
 @dcomp = apply { $_ ** 2 } @dcomp;
 my $dcomp = sqrt( sum( 0, @dcomp ) ) / 20;
 return $dcomp;
}

非常感谢您的回答或建议

re:小问题

这很好,并且是(某些)
List::Util
List::MoreUtils
模块的常见问题

删除警告的一种方法就是预先声明那些
特殊变量,如下所示:

our ($a, $b);
另一种方法是在
成对
之前加上:

no warnings 'once';
有关$a和$b的更多信息,请参阅


/I3az/

%{$foo}
$foo
视为散列引用并取消引用;类似地,
@{}
将取消对数组引用的引用。由于
comp
将散列作为列表返回(散列在传递给函数和从函数传递过来时变为列表),而不是散列引用,
%{}
是错误的。您可以省略
%{}
,但是
是一种特殊形式,需要一个哈希,而不是作为列表传递的哈希。要将
comp
的结果传递给
comp
需要返回一个散列引用,然后该散列引用被取消引用

您的
dcomp
还有另一个问题,即
值的顺序
(如所述)“以明显的随机顺序返回”,因此传递给
成对
块的值不一定是同一个字符的值。您可以使用散列切片,而不是
。现在我们回到
comp
返回散列(作为列表)

这并不能解决如果字符只出现在
$\u0]
$\u1]
中的一个中会发生什么情况


uniq
留给读者作为练习。

您的代码中有一些错误。首先,请注意:

由于音译表是在编译时生成的,无论是
SEARCHLIST
还是
REPLACEMENTLIST
都不会受到双引号插值的影响

所以你的计数方法不正确。我还认为你在两两使用
。很难评估什么是正确的用法,因为您没有给出一些简单输入应该得到什么输出的示例

在任何情况下,我都会将此脚本重新编写为(其中包含一些调试语句):


只要浏览一下您提供的代码,我就会这样写。我不知道这是否会按照你希望的方式工作

use strict;
use warnings;
our( $a, $b );

use List::Util;
use List::MoreUtils;

my @alphabet = split '', 'ARNDCQEGHILKMFPSTWYV';
my $gapchr = '-';
# Takes a sequence and returns letter => occurrence count pairs as hash.
sub getcounts {
  my( $sequence ) = @_;
  my %counts;
  for my $chr (@alphabet) {
    $counts{$chr} = () = $sequence =~ /($chr)/g;
    # () = forces list context
  }
  $counts{'gap'} = () = $sequence =~ /($gapchr)/g;
  return %counts if wantarray; # list context
  return \%counts; # scalar context
  # which is what happens inside of %{  }
}

# Takes a sequence and returns letter => fractional composition pairs as a hash
sub comp {
  my( $sequence ) = @_;
  my %counts = getcounts( $sequence );
  my %comp;
  for my $chr (@alphabet) {
    $comp{$chr} = $comp{$chr} / ( length( $sequence ) - $counts{'gap'} );
  }
  return %comp if wantarray; # list context
  return \%comp; # scalar context
}

# Takes two sequences and returns a measure of the composition difference
#   between them, as a scalar.
sub dcomp {
  my( $seq1, $seq2 ) = @_;
  my @dcomp = pairwise { $a - $b }
    @{[ values( %{ comp( $seq1 ) } ) ]},
    @{[ values( %{ comp( $seq2 ) } ) ]};
  # @{[ ]} makes a list into an array reference, then dereferences it.
  # values always returns a list
  # a list, or array in scalar context, returns the number of elements
  # ${  } @{  } and %{  } forces their contents into scalar context

  @dcomp = apply { $_ ** 2 } @dcomp;
  my $dcomp = sqrt( sum( 0, @dcomp ) ) / 20;
  return $dcomp;
}

您需要知道的最重要的事情之一是标量、列表和空上下文之间的差异。这是因为在不同的上下文中,所有事物的行为都是不同的。

您会在子块中或在全局名称空间中进行声明吗(我的术语不太正确)?在我看来,如果我只使用一次该方法,那么我会喜欢前者,如果我在许多地方使用它,那么我会喜欢后者。在这种情况下,将
我们的($a,$b)
放在程序的顶部就可以了$a和$b是特殊的,因此不应用于其他任何条排序和模块,如List::Util。问题在于,
warningonce
没有考虑$a和$b特殊变量,除了
sort
之外,请参阅更多关于为什么/如何发生这种情况的解释+1 hash ref错误在哪一行?关于小问题,请参阅。hash ref error在&comp处$comp{$chr}=$comp{$chr}/(长度($[0])-$comp{'gap})我认为hash片段必须用@{[]}括起来?现在我知道了价值观的危险性(),谢谢。啊,是的,我知道了背景。”如果wantarray’是一个巧妙的把戏,那么在不深入生物学的情况下(似乎不是这样),序列间隙并不构成序列“组成”的差异,因为它们不是(20个氨基酸中)字母表中的一个字母。20是(任意地)将$dcomp从0规范化为1。我现在拿到地图了…谢谢!
#!/usr/bin/perl

use List::AllUtils qw( sum );
use YAML;

our ($a, $b);
my @alphabet = ('A' .. 'Z');
my $gap = '-';

my $seq1 = 'ABCD-EFGH--MNOP';
my $seq2 = 'EFGH-ZZZH-KLMN';

print composition_difference($seq1, $seq2);

sub getcounts {
    my ($seq) = @_;
    my %counts;
    my $pattern = join '|', @alphabet, $gap;
    $counts{$1} ++ while $seq =~ /($pattern)/g;
    warn Dump \%counts;
    return \%counts;
}

sub fractional_composition_pairs {
    my ($seq) = @_;
    my $comp = getcounts( $seq );
    my $denom = length $seq - $comp->{$gap};
    $comp->{$_} /= $denom for @alphabet;
    warn Dump $comp;
    return $comp;
}

sub composition_difference {
    # I think your use of pairwise in the original script
    # is very buggy unless every sequence always contains
    # all the letters in the alphabet and the gap character.
    # Is the gap character supposed to factor in the computations here?

    my ($comp1, $comp2) = map { fractional_composition_pairs($_) } @_;
    my %union;
    ++ $union{$_} for (keys %$comp1, keys %$comp2);

    my $dcomp;
    {
        no warnings 'uninitialized';
        $dcomp = sum map {
            ($comp1->{$_} - $comp2->{$_}) ** 2
        } keys %union;
    }

    return sqrt( $dcomp ) / 20; # where did 20 come from?
}
use strict;
use warnings;
our( $a, $b );

use List::Util;
use List::MoreUtils;

my @alphabet = split '', 'ARNDCQEGHILKMFPSTWYV';
my $gapchr = '-';
# Takes a sequence and returns letter => occurrence count pairs as hash.
sub getcounts {
  my( $sequence ) = @_;
  my %counts;
  for my $chr (@alphabet) {
    $counts{$chr} = () = $sequence =~ /($chr)/g;
    # () = forces list context
  }
  $counts{'gap'} = () = $sequence =~ /($gapchr)/g;
  return %counts if wantarray; # list context
  return \%counts; # scalar context
  # which is what happens inside of %{  }
}

# Takes a sequence and returns letter => fractional composition pairs as a hash
sub comp {
  my( $sequence ) = @_;
  my %counts = getcounts( $sequence );
  my %comp;
  for my $chr (@alphabet) {
    $comp{$chr} = $comp{$chr} / ( length( $sequence ) - $counts{'gap'} );
  }
  return %comp if wantarray; # list context
  return \%comp; # scalar context
}

# Takes two sequences and returns a measure of the composition difference
#   between them, as a scalar.
sub dcomp {
  my( $seq1, $seq2 ) = @_;
  my @dcomp = pairwise { $a - $b }
    @{[ values( %{ comp( $seq1 ) } ) ]},
    @{[ values( %{ comp( $seq2 ) } ) ]};
  # @{[ ]} makes a list into an array reference, then dereferences it.
  # values always returns a list
  # a list, or array in scalar context, returns the number of elements
  # ${  } @{  } and %{  } forces their contents into scalar context

  @dcomp = apply { $_ ** 2 } @dcomp;
  my $dcomp = sqrt( sum( 0, @dcomp ) ) / 20;
  return $dcomp;
}