[英]Splitting a changing string with perl
我在perl中有一堆看起來像這樣的字符串:
10 NE HARRISBURG
4 E HASWELL
2 SE OAKLEY
6 SE REDBIRD
PROVO
6 W EADS
21 N HARRISON
我需要做的是刪除城市名稱前面的數字和字母。 我遇到的問題是各個城市之間的差異很大。 數據幾乎從不相同。 是否可以刪除此數據並將其保存在單獨的字符串中?
嘗試這個:
for my $s (@strings) {
my @fields = split /\s+/, $s, 3;
my $city = $fields[-1];
}
您可以測試數組大小以確定字段數:
my $n = @fields;
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,如果只想運行一個字符串,則可以執行以下操作:
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";
看起來您總是想要split()結果中的最后一個元素。 或者,您可以使用m /(\\ S +)$ /。
我們不能假設總是有一個城市名稱並且它出現在行的最后嗎? 如果是這種情況,請分割線並保留其最后一部分。 這是一個划線員命令行解決方案:
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
#!/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();
#!/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的建議和示例進行更改。 這將去除前導數字和方向,並且如果數字或方向(或兩者都缺失)不會中斷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.