Split line with perl

2019-02-25 21:32发布

   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))

How to split this with perl in:

   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))

5条回答
Evening l夕情丶
2楼-- · 2019-02-25 21:49

The best way is to use the split command using a zero-width lookahead:

$string = "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))";

@split_string = split /(?=\b\w+:)/, $string;
查看更多
啃猪蹄的小仙女
3楼-- · 2019-02-25 21:51

This should do it. line.txt contains "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))"

#!/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";
}
查看更多
做自己的国王
4楼-- · 2019-02-25 21:57

Contrary to what many are saying in their answers, you do not need lookahead (other than the Regex's own), you would only need to capture part of the delimiter, like so:

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

My full solution below:

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 } );
}

Dump looks like this:

%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'
   }
查看更多
欢心
5楼-- · 2019-02-25 22:01
$string = "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))";
@words = split(' ', $string);

@lines = undef;
@line = shift(@words);
foreach $word (@words)
{
    if ($word =~ /:/)
    {
        push(@lines, join(' ', @line));
        @line = undef;
    }
    else
    {
        push(@line, $word);
    }
}

print join("\n", @lines);
查看更多
淡お忘
6楼-- · 2019-02-25 22:04

Use a lookahead assertion:

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

Output

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))
查看更多
登录 后发表回答