Расщепление изменяющейся строки с помощью Perl - PullRequest
0 голосов
/ 23 июля 2010

У меня есть куча строк в Perl, которые выглядят так:

10 NE HARRISBURG
4 E HASWELL
2 SE OAKLEY
6 SE REDBIRD
PROVO
6 W EADS
21 N HARRISON

Что мне нужно сделать, это удалить цифры и буквы перед названиями городов.Проблема, которую я имею, состоит в том, что это сильно варьируется от города к городу.Данные почти никогда не совпадают.Можно ли удалить эти данные и сохранить их в отдельной строке?

Ответы [ 5 ]

3 голосов
/ 23 июля 2010

Попробуйте:

for my $s (@strings) {
    my @fields = split /\s+/, $s, 3;
    my $city = $fields[-1];
}

Вы можете проверить размер массива, чтобы определить количество полей:

my $n = @fields;
2 голосов
/ 23 июля 2010
my @l = (
'10 NE HARRISBURG',
'4 E HASWELL',
'2 SE OAKLEY',
'6 SE REDBIRD',
'PROVO',
'6 W EADS',
'21 N HARRISON',
);

foreach(@l) {

в соответствии с hoobs я изменил регулярное выражение

    my($beg, $rest) = ($_ =~ /^(\d*\s(?:[NS]|[NS]?[EW])*)?(.*)$/);
    print "beg=$beg \trest=$rest\n";    
}

вывод:

beg=10 NE   rest=HARRISBURG
beg=4 E     rest=HASWELL
beg=2 SE    rest=OAKLEY
beg=6 SE    rest=REDBIRD
beg=    rest=PROVO
beg=6 W     rest=EADS
beg=21 N    rest=HARRISON

для Синдзё, если вы хотите запустить только одну строку, вы можете сделать:

  my($beg, $rest) = ($l[3] =~ /^(\d*\s(?:[NS]|[NS]?[EW])*)?(.*)$/);
  print "beg=$beg \trest=$rest\n";

и чтобы избежать предупреждения о неинициализированном значении, вы должны проверить, определен ли $ beg:

print defined$beg?"beg=$beg\t":"", "rest=$rest\n";
1 голос
/ 24 июля 2010

Regex Solution

Решение 1. Сохраните все (решение vol7ron, отправленное по электронной почте)


#!/usr/bin/perl -w    

use strict; 
use Data::Dumper;   

   sub main{    
      my @strings = (    
                      '10 NE HARRISBURG'    
                    , '4 E HASWELL'    
                    , '2 SE OAKLEY'    
                    , '6 SE REDBIRD'    
                    , 'PROVO'    
                    , '6 W EADS'    
                    , '21 N HARRISON'    
                    , '32 SAN FRANCISCO' 
                    , ''   
                    , '15 NEW YORK'    
                    , '15 NNW NEW YORK'    
                    , '15 NW NEW YORK'     
                    , 'NW NEW YORK'    
                    );       

      my %hash;
      my $count=0;
      for (@strings){    
         if (/\d*\s*[NS]{0,2}[EW]{0,1}\s+/){
            # if there was a speed / direction
            $hash{$count}{wind} = $&;
            $hash{$count}{city} = $';
         } else {
            # if there was only a city
            $hash{$count}{city} = $_;
         }
         $count++;
      }    

      print Dumper(\%hash);  
   }    

   main();  

Решение 2. Удалите то, что вам не нужно


#!/usr/bin/perl -w    

use strict;    

   sub main{    
      my @strings = (    
                      '10 NE HARRISBURG'    
                    , '4 E HASWELL'    
                    , '2 SE OAKLEY'    
                    , '6 SE REDBIRD'    
                    , 'PROVO'    
                    , '6 W EADS'    
                    , '21 N HARRISON'    
                    , '32 SAN FRANCISCO'    
                    , '15 NEW YORK'    
                    , '15 NNW NEW YORK'    
                    , '15 NW NEW YORK'     
                    , 'NW NEW YORK'     
                    );    

      for my $elem (@strings){    
         $elem =~ s/\d*\s*[NS]{0,2}[EW]{0,1}\s+(\w*)/$1/;    
      }    

      $"="\n";    
      print "@strings\n";        
   }    

   main();    

Обновление:

Внесение изменений с помощью vol7ron Предложение и пример использования оператора повторения сработали.Это исключит начальные цифры и направление и не прервется, если цифры или направление (или оба) отсутствуют.

1 голос
/ 23 июля 2010

Разве мы не можем предположить, что всегда есть название города и что оно появляется последним в строке? Если это так, разделите строку и оставьте последнюю часть. Вот решение для командной строки с одним вкладышем:

perl -lne 'split ; print $_[-1]' input.txt

Выход:

HARRISBURG
HASWELL
OAKLEY
REDBIRD
PROVO
EADS
HARRISON

Обновление 1

Это решение не будет работать, если вы составите названия городов, такие как SAN FRANCISCO (случай указан в комментарии ниже).

Откуда поступают ваши входные данные? Если вы сгенерировали его самостоятельно, вы должны добавить разделители. Если кто-то сгенерировал его для вас, попросите его восстановить его разделителями. Разбор этого станет детской игрой.

# replace ";" for your delimiter
perl -lne 'split ";" ; print $_[-1]' input.txt
1 голос
/ 23 июля 2010

Похоже, что вы всегда хотите самый последний элемент в результате split ().Или вы можете пойти с m / (\ S +) $ /.

...