【问题标题】:Splitting specific strings in an array?拆分数组中的特定字符串?
【发布时间】:2013-07-23 11:45:02
【问题描述】:

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

rs30000489
rs903484
rs24567;rs324987;rs234985
rs5905002
rs32456;rs2349085

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

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 中的循环时遇到了麻烦。如果您有任何想法,请告诉我!谢谢!

【问题讨论】:

  • 这听起来像XY-problem。你真正想要做什么?将两个 ID 列表相互匹配?
  • 另外,在编写关键描述时应该更加小心。这是什么意思:without strings with semicolons and multiple rsIDs 没有带分号的字符串听起来像是它唯一的分号。您几乎应该总是展示而不是描述。
  • 而你的 'split' 并不是真正的分裂。它与; 匹配,然后将其推送到@new
  • @TLP 是的,我的意思是我要检查的数组没有任何字符串实例,例如 rs#;rs#;rs# 就像 '@myarray' 数组一样
  • @user2560686 现在,这对你来说可能有意义,但对我来说,你只是说@otherarray 有其他类型的字符串。如果您考虑一下,这并没有真正说明什么。为了让事情变得更简单,您应该只显示示例数据,就像您对第一个数组所做的那样。

标签: regex perl split


【解决方案1】:

你没有说你想用这两个数组做什么,但如果我理解你的问题,听起来你可能想找到出现在两个列表中的所有那些 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

【讨论】:

    【解决方案2】:

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

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

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

    您可以编写与第二个完全相同的第一个循环。

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

    或者更好

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

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

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

    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
    

    【讨论】:

      【解决方案3】:

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

      #!/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;
      

      【讨论】:

        猜你喜欢
        • 2020-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-18
        • 1970-01-01
        • 1970-01-01
        • 2015-11-25
        相关资源
        最近更新 更多