0

私はperlにたくさんの文字列を持っていますが、それらはすべて次のようになります:

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

私がしなければならないのは、都市名の前から数字と文字を削除することです。私が抱えている問題は、それが都市ごとに大きく異なるということです。データが同じになることはほとんどありません。このデータを削除して別の文字列に保持することは可能ですか?

4

5 に答える 5

3

これを試して:

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

配列のサイズをテストして、フィールドの数を決定できます。

my $n = @fields;
于 2010-07-23T14:55:23.640 に答える
2
my @l = (
'10 NE HARRISBURG',
'4 E HASWELL',
'2 SE OAKLEY',
'6 SE REDBIRD',
'PROVO',
'6 W EADS',
'21 N HARRISON',
);

foreach(@l) {

フーブによると、正規表現を変更しました

    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

shinjuo の場合、文字列を 1 つだけ実行する場合は、次のようにします。

  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";
于 2010-07-23T14:59:07.373 に答える
1

split() の結果で常に最後の要素が必要なようです。または、m/(\S+)$/ を使用できます。

于 2010-07-23T14:54:31.683 に答える
1

常に都市名があり、それが行の最後にあると仮定できませんか? その場合は、行を分割して最後の部分を保持します。ワンライナーのコマンド ライン ソリューションを次に示します。

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
于 2010-07-23T14:58:52.143 に答える
1

正規表現ソリューション


解決策 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の提案と例で変更を加えるとうまくいきました。これにより、先頭の数字と方向が取り除かれ、数字または方向 (またはその両方) が失われても壊れません。

于 2010-07-23T23:59:24.183 に答える