2014-04-18 47 views
0

換檔圖我:分割字符串在Perl中

my $string = aaaa bbbb "ccccc ddddd eeee" fffff "ggggg hhhh"; 

我想要拆分此字符串:

aaaa  
bbbb 
cccc dddd eeee 
ffff 
gggg hhhh 

我如何使用拆分辦呢?

我認爲應該是這個樣子的僞代碼:

split(/IF ONWARD SYMBOL " APPEARS EVENT COUNT DO PATTERN: \s ELSE: "/ $string); 

注:需要保持字符串中的字符的順序

+3

哪裏是你的代碼失敗? – Robin

回答

1

而不是使用split最好是使用全局正則表達式將字符串分割成引用和不引用的部分。

use strict; 
use warnings; 

my $string = 'aaaa bbbb "ccccc ddddd eeee" fffff "ggggg hhhh"'; 

my @split = $string =~/" [^"]* " | \S+ /xg; 

print "$_\n" for @split; 

輸出

aaaa 
bbbb 
"ccccc ddddd eeee" 
fffff 
"ggggg hhhh" 
0

你可以內外分別ouside雙引號匹配的話,並在循環中使用/g,像這樣:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $string = 'aaaa bbbb "ccccc ddddd eeee" fffff "ggggg hhhh"'; 

while ($string =~ m/(\w+)|"([^"]+)"/g) { 
    print $1 || $2, "\n"; 
} 

ř unning:

$ perl t.pl 
aaaa 
bbbb 
ccccc ddddd eeee 
fffff 
ggggg hhhh 

順便說一句,你可以實現上述的只有一條線路:

@field = grep { defined } ($string =~ m/(\w+)|"([^"]+)"/g); 
+0

我確信示例字​​符串不是實時數據,而且很可能實際數據字段不匹配'\ w +' – Borodin

+0

注意可以使用*分支重置*模式'(? | ...)'這裏有一個將所有捕獲內容存儲在同一個變量的替代列表中的效果。所以'm /(?|(\ w +)|「([^」] +)「)/ xg'會設置'$ 1',而不管哪一個分支實際匹配,你也可以只寫'print $ 1 || $ 2' 'while'循環 – Borodin

+0

@Borodin非常感謝您的建議,更新後的答案,第一個版本現在好多了,Perl 5.10.0引入了'(?| ...)',但不幸的是我使用Perl 5.8 .8在這一刻,但是,知道它還是很好的,謝謝。 –

4

您可以用方便的模塊Text::ParseWords從Perl的核心庫做到這一點:

use strict; 
use warnings; 
use Data::Dumper; 
use Text::ParseWords; 

my $string = qq(aaaa bbbb "ccccc ddddd eeee" fffff "ggggg hhhh"); 
my @parts = quotewords('\s+', 0, $string); 
print Dumper \@parts; 

輸出:

$VAR1 = [ 
      'aaaa', 
      'bbbb', 
      'ccccc ddddd eeee', 
      'fffff', 
      'ggggg hhhh' 
     ]; 
0

與拆分方式:

use strict; 
use warnings; 

my $string = '"aaaa" bbbb kkkk "ccccc ddddd eeee" fffff eeee "ggggg hhhh"'; 

my @res = grep {$_} split(/ *"([^"]*)" *| +/, $string); 

print join($/, @res);