Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.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
在perl中处理嵌套分隔符_Perl_Delimiter - Fatal编程技术网

在perl中处理嵌套分隔符

在perl中处理嵌套分隔符,perl,delimiter,Perl,Delimiter,我试图获取每个键的值,并再次尝试从结果散列中分割逗号分隔的值,如果我在任何值中找到分号,我会将左值和右值存储在单独的散列键中 像下面这样 1 7802315095\d\d,7802315098\d\d;7802025001\d\d,7802025002\d\d,7802025003\d\d,7802025004\d\d,7802025005\d\d,7802025006\d\d,7802025007\d\d 2 7802315095\d\d,7802025002\d\d,78020250

我试图获取每个键的值,并再次尝试从结果散列中分割逗号分隔的值,如果我在任何值中找到分号,我会将左值和右值存储在单独的散列键中

像下面这样

1 
7802315095\d\d,7802315098\d\d;7802025001\d\d,7802025002\d\d,7802025003\d\d,7802025004\d\d,7802025005\d\d,7802025006\d\d,7802025007\d\d 

2 
7802315095\d\d,7802025002\d\d,7802025003\d\d,7802025004\d\d,7802025005\d\d,7802025006\d\d,7802025007\d\d
是否有一种方法可以处理子程序中的所有内容?我能让代码更简单些吗

更新:

我尝试在一次快照中拆分字符串,但它只是用分号拾取值,而忽略所有内容

1.#split the value of result_hash{$key}  again by , and see whether any chunk is seperated by ;
2. #every chunk without ; and value on left  with ; should be stored in   
 @{$final_hash{"eto"}} =   ['7802315095\d\d','7802315098\d\d','7802025002\d\d','7802025003\d\d','7802025004\d\d','7802025005\d\d','7802025006\d\d','7802025007\d\d']  ;
3.#Anything found on the right side of ; has to be stored in  
 @{$final_hash{"pro"}} = ['7802025001\d\d'] ;   
}

帮助后我的更新代码

foreach my $key (sort keys %result_hash ){
#   print "$key \n";
#   print "$result_hash{$key} \n";
my ($o,$t) = split(/,|;/, $result_hash{$key});
   print "Left : $o \n";
   print "Left : $t \n";
   #push @{$final_hash{"eto"}}, $o;
   #push @{$final_hash{"pro"}} ,$t;
 }
子比较结果
{   

打开我的$fh,更新在末尾添加了一个两遍正则表达式


只需系统地进行,一步一步地分析字符串。事实上,您需要连续的拆分和特定的分隔规则,这使得在一次操作中很难做到。最好有一个清晰的方法,而不是一个怪物语句

sub Compare_results
{   
  open my $fh, '<', 'Data_File.txt' or die $!;
  # split by colon and further split by , and ; if any (done in insert_array)
  my %result_hash = map { chomp; split ':', $_ } <$fh> ; 
  foreach  ( sort { $a <=> $b }  (keys %result_hash) )
  { 
     ($_ < 21) 
        ? insert_array($result_hash{$_}, "west")
        : insert_array($result_hash{$_}, "east");
  } 
}


 sub insert_array()
 {
   my ($val,$key) = @_;
   foreach my $field (split ',', $val)
   {   
     $field =~ s/^\s+|\s+$//g;    # /  turn off editor coloring
     if ($field !~ /;/) {
        push @{ $file_data{"pto"}{$key} }, $field ;
     }
     else {
       my ($left, $right) = split ';', $field;
       push  @{$file_data{"pto"}{$key}}, $left if($left ne '') ;
       push @{$file_data{"ero"}{$key}}, $right if($right ne '')  ;
    }
   }  
  }
谢谢你的评论


出于好奇,这里有两个正则表达式

sub Compare_results {
    my (@eto, @pro);
    while (<DATA>) {
        my ($val) = /:(.*)/;
        foreach my $field (split ',', $val)
        # ... same
    }
    # assign to %final_hash, return from sub
}

好主意,但是如果你在
/[,;]/
上进行拆分,你如何判断哪些字段是“正确的”(在
的右边)?它返回一个所有字段的列表,在
之间,按照它们发生的顺序。(你写的内容将列表分配给两(2)个字段。)标量,所以在拆分后只得到前两个元素。)我编辑了您的添加内容——将长注释移到自己的行中,这样就不必滚动阅读它,并添加了一条由regex编写的注释
#/…
,该注释关闭了编辑器错误的红色着色。(经常这样做——在regex之后,所有内容都变为红色。)如果您不喜欢,请还原更改--单击我的用户名上方的“已编辑(时间)”,您将看到修订,每个修订旁边都有按钮。其中一个按钮上写着“回滚”,单击要回滚到的修订版本。@zdim:请告诉我如何拆分包含两个分隔符的数据,例如:1,2,3,4,5,6,7;8,9,10,11,12,我想将之后的所有内容存储在一个数组中,并直接存储在另一个数组中。请帮助我使用一次性拆分函数。O/P array1=[1,2,3,4,5,6,7]和array2=[8,9,10,11,12]现在,我的答案中最后一个例子的两次变化。首先弹出--
@left=split“,”,(/([^;]+)/)[0]
@right=split“,”,(/;([^;]+)/)[0];
。如果要处理的字符串在
$
中,请使用
($str=~/)[0]
。添加
让@left
看到它。需要
(…)[0]
,因为匹配会返回一个列表,如果将其传递给
拆分
,它将在标量上下文中计算为1(长度)。因为你会得到一个列表,所以真正的一次尝试更难,但需要将其拆分为两个。如果我有更好的想法,我会发布另一条评论。但它是否试图将相同的数据拆分两次?确定,这值得一个新问题吗?@LearningCpp我更新了答案--完成了完整程序的代码,使用你的数据进行了测试,并添加了一些评论。谢谢@zdim,我已经使用了你最后一段代码,但是它附加了一个额外的\to\d(即\\d),你能解释一下map{chomp;(split':',$)[1]};我添加了chomp以消除empties@LearningCpp这很奇怪——它没有添加到我的测试中(我发布为输出的内容是从终端复制的),它不应该这样做。regex的输出是相同的。行如下。它选择新行。然后它按
拆分,生成两个字段。
映射是这样的,它对每一行执行此操作,并发送整个列表。因此,这些是对,您可以直接将其分配给哈希。这是合法的:
我的%h=(1,'1',2,'2');
它将它们配对,
键=>值,
分配到散列的一种非常好的方式。@LearningCpp这里已经很晚了,我现在就去(对于那些zzzz)。让我知道,我将在几个小时后回来。如果这些评论不够好,我可以添加到帖子中。这是我的输出,我使用您发布的地图代码['7802261004\\d\\d'、'7802261046\\d\\d'、'7802261064\\d\\d'、'780226186\\d\\d'、'7802293001\\d\\d'];查看出了什么问题
use warnings 'all';
use strict;   
use feature 'say';

my (%result_hash, %final_hash); 

Compare_results(); 

say "$_ => $result_hash{$_}" for sort keys %result_hash;
say '---';
say "$_ => [ @{$final_hash{$_}} ]" for sort keys %final_hash;

sub Compare_results 
{   
    %result_hash = map { chomp; split ':', $_ } <DATA>;

    my (@eto, @pro);
    foreach my $val (values %result_hash)
    {   
        foreach my $field (split ',', $val)
        {   
            if ($field !~ /;/) { push @eto, $field }
            else { 
                my ($left, $right) = split ';', $field;
                push @eto, $left;
                push @pro, $right;
            }
        }    
    }        
    $final_hash{eto} = \@eto;
    $final_hash{pro} = \@pro;
    return 1;                  # but add checks above
}
1 => ... (what you have in the question) --- eto => [ 7802315095\d\d 7802315098\d\d 7802025002\d\d 7802025003\d\ d ... pro => [ 7802025001\d\d ]
sub Compare_results {
    my (@eto, @pro);
    while (<DATA>) {
        my ($val) = /:(.*)/;
        foreach my $field (split ',', $val)
        # ... same
    }
    # assign to %final_hash, return from sub
}
sub compare_rx {
    my @data = map { (split ':', $_)[1] } <DATA>;
    $final_hash{eto} = [ map { /([^,;]+)/g  } @data ];
    $final_hash{pro} = [ map { /;([^,;]+)/g } @data ];
    return 1;
}
my (@eto, @pro);
while (<DATA>) {
    my ($data) = /:(.*)/;
    push @eto, $data =~ /([^,;]+)/g; 
    push @pro, $data =~ /;([^,;]+)/g;
}