2011-09-07 82 views
4

我有一個字符串aa:bb::cc:yy:zz需要拆分的方式,我有一個陣列aa:bb::cc,yy,zz。即我想從最後創建兩個子字符串:作爲分隔符並保留爲數組的一個元素。達到此目的的最佳方式是什麼?perl:如何拆分?

例如:

aa:bb::cc:yy:zz --> ['aa:bb::cc','yy','zz'] 

dd:ff:gg:dd:ee:ff:fg --> ['dd:ff:gg:dd:ee','ff','gg'] 

我存儲IP地址:端口:協議在一個文件中的關鍵和拆分室內用「:」來獲取IP,端口,原回事情做工精細,當IP地址僅限於Ipv4。現在我想將它移植到Ipv6,在這種情況下,IP地址包含「:」,因此我無法通過使用「:」分割來獲得正確的IP地址。

+0

這將是更安全的存儲你的'(IP,端口)'使用標準化'[IP地址]對:端口'格式。在[AnyEvent :: Socket](https://metacpan.org/module/AnyEvent::Socket)模塊中的'parse_hostport' /'format_hostport'有助於處理它。 – dolmen

回答

11

如何:

#!/usr/local/bin/perl 
use Data::Dump qw(dump); 
use strict; 
use warnings; 

my $x = 'dd:ff:gg:dd:ee:ff:fg'; 
my @l = $x =~ /^(.*?):([^:]+):([^:]+)$/g; 
dump @l; 

輸出:

("dd:ff:gg:dd:ee", "ff", "fg") 
+0

請注意,這將失敗'兩個或更少對'字符串,如'dd:ff'或'dd' – yko

+0

這對我來說不是問題,因爲我期望3個參數的最小值。 – kumar

+0

THanks M42,完美的解決方案。 – kumar

3
$ perl -wE '$_="aa:bb::cc:yy:zz"; say join "\n", split /:([^:]+):([^:]+)$/, $_;' 
aa:bb::cc 
yy 
zz 

更新:你沒有提到這是爲了解析IP地址。如果是,你可能會更好試圖找到一個模塊上CPAN

+0

感謝TLP,這也像一個魅力。 – kumar

+0

@kumar歡迎您。它基本上和M42一樣。 – TLP

2
$ perl -e'$_="aa:bb::cc:yy:zz"; @f=/(.*):([^:]+):(.+)/; print "$_\n" for @f' 
aa:bb::cc 
yy 
zz 

$ perl -e'$_="dd:ff:gg:dd:ee:ff:fg"; @f=/(.*):([^:]+):(.+)/; print "$_\n" for @f' 
dd:ff:gg:dd:ee 
ff 
fg 
3

我會做的過於激進的split後面加入。我認爲當你不使用複雜的正則表達式進行拆分時,結果更具可讀性。所以:

my $string = 'aa:bb::cc:yy:zz'; 
my @split_string = split(/:/, $string); 
my @result = (join(':', @split_string[0..scalar(@split_string)-3]), $split_string[-2], $split_string[-1]); 
print join(', ', @result), "\n"; 

爲您提供:

aa:bb::cc, yy, zz 

你必須做一些數組邊界上@split_string檢查你開始索引它像之前。

4

此代碼將正確處理這種情況時,$字符串包含2個或更少的對:

my $string = 'aa:bb::cc:yy:zz'; 
my @data = split /:/, $string; 
if (@data > 2) { 
    unshift @data, join ':', splice @data, 0, -2; 
} 

# $string = 'aa:bb::cc:yy:zz'; 
# @data contains ('aa:bb::cc', 'yy', 'zz') 

# $string = 'aa:bb'; 
# @data contains ('aa', 'bb')