用perl拆分行

用perl拆分行,perl,line-processing,Perl,Line Processing,如何使用perl将其拆分为: title: Football team: Real Madrid stadium: Santiago Bernabeu players: Zinédine Zidane, Ronaldo, Luís Figo, Roberto Carlos, Raúl personnel: José Mourinho (head coach) Aitor Karanka (assistant coach (es)) 使用前瞻断言: title: Football

如何使用perl将其拆分为:

   title: Football team: Real Madrid stadium: Santiago Bernabeu players: Zinédine Zidane, Ronaldo, Luís Figo, Roberto Carlos, Raúl personnel: José Mourinho (head coach) Aitor Karanka (assistant coach (es))

使用前瞻断言:

   title: Football
   team: Real Madrid
   stadium: Santiago Bernabeu
   players: Zinédine Zidane Ronaldo Luís Figo Roberto Carlos Raúl
   personnel: José Mourinho (head coach) Aitor Karanka (assistant coach (es))
输出

say for split /(?=\w+:)/, $real_madrid_string;

最好的方法是使用
split
命令,使用零宽度前瞻:

title: Football
team: Real Madrid
stadium: Santiago Bernabeu
players: Zinédine Zidane Ronaldo Luís Figo Roberto Carlos Raúl
personnel: José Mourinho (head coach) Aitor Karanka (assistant coach (es))

这应该可以做到。line.txt包含“标题:足球队:皇家马德里体育场:圣地亚哥伯纳乌球员:齐丁·齐达内、罗纳尔多、路易斯·菲戈、罗伯托·卡洛斯、劳尔人事:何塞·穆里尼奥(主教练)艾托·卡兰卡(助理教练))”

#/usr/bin/perl
严格使用;
使用警告;
my$fn=“./line.txt”;
开放式(单位:fn美元);
我的@lines=;
我的%hash;
我的$hashKey;
foreach my$行(@行){
$line=~s/\n//g;
my@split1=拆分(“+”,美元行);
foreach my$split(@split1){
如果($split=~m/:$/){
$hashKey=$split;
}否则{
if(已定义($hash{$hashKey})){
$hash{$hashKey}=$hash{$hashKey}.$split.“;
}否则{
$hash{$hashKey}=$split.“;
}
}
}
}
关闭(IN);
foreach my$密钥(密钥%hash){
打印$key.:“$hash{$key}.\n”;
}

与许多人在回答中所说的相反,您不需要前瞻(除了正则表达式本身),只需要捕获部分分隔符,如下所示:

#!/usr/bin/perl
use strict;
use warnings;

my $fn="./line.txt";

open(IN,$fn);
my @lines=<IN>;

my %hash;
my $hashKey;

foreach my $line (@lines){
        $line=~s/\n//g;
        my @split1=split(" +",$line);
        foreach my $split (@split1){
                if($split=~m/:$/){
                        $hashKey=$split;
                }else{
                        if(defined($hash{$hashKey})){
                                $hash{$hashKey}=$hash{$hashKey}.$split." ";
                        }else{
                                $hash{$hashKey}=$split." ";
                        }
                }
        }
}

close(IN);


foreach my $key (keys %hash){
        print $key.":".$hash{$key}."\n";
}
我的完整解决方案如下:

my @hash_fields = grep { length; } split /\s*(\w+):\s*/;

这是行不通的,因为Perl没有数组数组的概念。第一次
推送
将把
@行
的内容连接到
@行
的末尾。为了让它工作,
@lines
必须是数组的引用数组,由
@line
生成@lines是字符串数组,我只会将字符串推到它中。在发布代码之前运行代码通常是个好主意。这根本不会运行。首先,我可以看到缺少一个分号
push
将数组作为它的第一个参数,您可能打算在那里连接。但即便如此,它也回避了一个问题,为什么要绕这么远的路?啊,我总是对要推动的论点的顺序感到困惑。至于原因,我是perl新手,没有考虑lookahead@Zaid当前位置我不会责怪Bwmat没有考虑未来。毕竟,有不止一种方法。对不起。。。出于使用Vim的习惯,我避开了
。如果将“players”翻译成另一种语言:“players”=“jucător”,则零宽度前瞻会找到字符“ă”,并在此处拆分。谢谢。@用户:您必须确保您的区域设置是正确的
\w
被明确设计为以与区域设置无关的方式使用,并且区域设置差异应该在后台处理。@用户:在这里查看如何处理区域设置:如果将“players”翻译成另一种语言:“players”=“jucător”,则零宽度的先行查找会找到字符“ă”而不是冒号:(一个被解释为非单词字符的单词字符)并在此处拆分。谢谢。那么您的Perl版本不够新,无法直接支持此操作。您可以尝试在
\P{Letter}上拆分
相反,但我想您还需要使用Perl选项使其进入UTF8类型的状态,可能使用Perl
-CSD
。也许其中一个就足够了。$value=~m/([^(]*)([((?:[^()]+|(?2))*[)]/g未定义(?)顺序。@user935420,不知道您遇到了什么问题。在我的草莓perl 5.12和ActivePerl 5.14中,它可以顺利工作。
#!/usr/bin/perl
use strict;
use warnings;

my $fn="./line.txt";

open(IN,$fn);
my @lines=<IN>;

my %hash;
my $hashKey;

foreach my $line (@lines){
        $line=~s/\n//g;
        my @split1=split(" +",$line);
        foreach my $split (@split1){
                if($split=~m/:$/){
                        $hashKey=$split;
                }else{
                        if(defined($hash{$hashKey})){
                                $hash{$hashKey}=$hash{$hashKey}.$split." ";
                        }else{
                                $hash{$hashKey}=$split." ";
                        }
                }
        }
}

close(IN);


foreach my $key (keys %hash){
        print $key.":".$hash{$key}."\n";
}
my @hash_fields = grep { length; } split /\s*(\w+):\s*/;
my %handlers
    = ( players   => sub { return [ grep { length; } split /\s*,\s*/, shift ]; }
      , personnel => sub { 
            my $value = shift;
            my %personnel;
            # Using recursive regex for nested parens
            while ( $value =~ m/([^(]*)([(](?:[^()]+|(?2))*[)])/g ) {
                my ( $name, $role ) = ( $1, $2 );
                $role =~ s/^\s*[(]\s*//;
                $role =~ s/\s*[)]\s*$//;
                $name =~ s/^\s+//;
                $name =~ s/\s+$//;
                $personnel{ $role } = $name;
            }
            return \%personnel;
        }
      );
my %hash = grep { length; } split /(?:^|\s+)(\w+):\s+/, <DATA>;
foreach my $field ( keys %handlers ) { 
    $hash{ $field } = $handlers{ $field }->( $hash{ $field } );
}
%hash: {
     personnel => {
                    'assistant coach (es)' => 'Aitor Karanka',
                    'head coach' => 'José Mourinho'
                  },
     players => [
                  'Zinédine Zidane',
                  'Ronaldo',
                  'Luís Figo',
                  'Roberto Carlos',
                  'Raúl'
                ],
     stadium => 'Santiago Bernabeu',
     team => 'Real Madrid',
     title => 'Football'
   }