拆分数组中的特定字符串?

时间:2013-07-23 11:45:02

标签: regex perl split

我有一个带有字符串的数组(@myarray):

rs30000489
rs903484
rs24567;rs324987;rs234985
rs5905002
rs32456;rs2349085

当我匹配另一个没有带分号和多个rsID的字符串的类似(@otherarray)数组时,使用以下代码:

for $1(0 .. $#otherarray) {
    for $m(1 .. $#myarray) {
        if ($myarray[$m] =~ /$otherarray[$i]/i) { 
            $IDmatch = 1;
        }
    }
}

该脚本与带分号的字符串中的任何ID都不匹配。我试着像这样分割分号字符串:

foreach $string (@myarray) {
    if ($string =~ m/;/) {
        push (@newarray, $string);
    }
}

返回数组@new:

rs24567;rs324987;rs234985
rs32456;rs2349085

然后我尝试将其拆分为一个共同的角色:

foreach $line (@new) {
    $line =~ tr/;//d;
    $line =~ s/rs/ rs/g;
    $line = split (/ /);
}

但是当我打印@new数组时,它只返回零。我知道这必须与我的循环有关,因为我在perl中使用循环时遇到了麻烦。如果您有任何想法,请告诉我!谢谢!

3 个答案:

答案 0 :(得分:2)

你没有说你想对这两个数组做什么,但如果我理解你的问题,那么你可能想要找到两个列表中出现的所有那些rsID。

此程序的工作原理是将第一个数组(使用比myarrayotherarray更好的名称)转换为具有所有ID作为键的哈希。然后,它使用grep查找哈希中出现的第二个数组中的所有数据,将它们推送到数组@dups

use strict;
use warnings;

my @myarray = qw(
  rs30000489
  rs903484
  rs24567;rs324987;rs234985
  rs5905002
  rs32456;rs2349085
);

my @otherarray = qw(
  rs3249487
  rs30000489
  rs325987
  rs324987
  rs234967
  rs32456
  rs234567
);

my %rsids = map { $_ => 1 } map { split /;/ } @myarray;

my @dups = grep $rsids{$_}, @otherarray;

print "$_\n" for @dups;

<强>输出

rs30000489
rs324987
rs32456

答案 1 :(得分:0)

关于Perl循环的一些事情。您以两种不同的方式编写了for循环。

for $1(0 .. $#otherarray) { ... }

foreach $line (@new) { ... }

你可以像第二个一样写第一个循环循环。

foreach $1 ( 0..$#otherarray) { .. }

或更好

foreach my $other_array_content ( @otherarray) { .. }

您使用的$1是一个特殊字符(在正则表达式中使用)。

然后您也可以使用split循环中的foreach

foreach my $data (@data) {
  foreach (split /;/,$data) {

  }
}

这是一个简短的解决方案,简而言之:

my @checked = qw(rs30000489
  rs9033484
  rs2349285
  rs5905402
  rs32456
);

my $idMatch = 0;
my @data    = <DATA>;

foreach my $data ( @data ) {
  foreach my $checked ( @checked ) {
    if ( $data =~ m/;/ ) {
      foreach my $data2 ( split /;/, $data ) {
        if ( $checked eq $data2 ) {
          $idMatch = 1;
        }
      }
    } else {
      if ($data eq $checked) {
        $idMatch = 1;
      }
    }
  }
}

print $idMatch;

__DATA__

rs30000489
rs903484
rs24567;rs324987;rs234985
rs5905002
rs32456;rs2349085

答案 2 :(得分:0)

如果您正在寻找独特的物品,首先应该考虑的是哈希。尝试:

#!/usr/bin/env perl

use strict;
use warnings;

# --------------------------------------

use charnames qw( :full :short   );
use English   qw( -no_match_vars );  # Avoids regex performance penalty

use Data::Dumper;

# Make Data::Dumper pretty
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Indent   = 1;

# Set maximum depth for Data::Dumper, zero means unlimited
local $Data::Dumper::Maxdepth = 0;

# conditional compile DEBUGging statements
# See http://lookatperl.blogspot.ca/2013/07/a-look-at-conditional-compiling-of.html
use constant DEBUG => $ENV{DEBUG};

# --------------------------------------
#       Name: unique
#      Usage: %hash = unique( @array );
#    Purpose: Create a hash of unique keys from array items.
# Parameters: @array -- May have multiple entries separated by a semi-colon
#    Returns:  %hash -- Unique keys of array items
#
sub unique {
  my @array = @_;
  my %hash  = ();

  for my $item ( @array ){
    my @items = split m{ \; }msx, $item;
    $hash{$_} ++ for @items;
  }

  return %hash;
}

# --------------------------------------

my @myarray = qw(
  rs30000489
  rs903484
  rs24567;rs324987;rs234985
  rs5905002
  rs32456;rs2349085
);

my @otherarray = qw(
  rs3249487
  rs30000489
  rs325987
  rs324987
  rs234967
  rs32456
  rs234567
);

my %my_hash = unique( @myarray );
print Dumper \%my_hash if DEBUG;

my %other_hash = unique( @otherarray );
print Dumper \%other_hash if DEBUG;

my %intersection = ();
for my $item ( keys %my_hash ){
  if( exists $other_hash{$item} ){
    $intersection{$item} ++;
  }
}
print Dumper \%intersection if DEBUG;