2014-02-07 54 views
0

我是新來的perl,目前正試圖解決一個問題。任何人都可以幫助我將不勝感激。 輸入字符串由Space分隔。我需要用不同的分隔符(比如pipe'|')生成一個輸出字符串,但是需要忽略雙引號內的空格。在Perl中:如何更改字符串的分隔符忽略那些雙引號內的字符?

例子:

 
Input String : 
Apple Mango "Banana/Tomato [, ANYTHING INSIDE QUOTE" Grapes - "-" Pineapple - - 
Desired Output String : 
Apple|Mango|"Banana/Tomato [, ANYTHING INSIDE QUOTE"|Grapes|-|"-"|Pineapple|-|- 

注:

  1. 我知道的Perl quotewords功能,但畢竟是死的慢特別是當我們需要處理數以百萬計的字符串。請讓我知道在這種情況下是否有任何正則表達式可以運行得更快。

  2. 不應刪除雙引號。需要如上所述的輸出。

回答

0

這應該工作:

s='Apple Mango "Banana/Tomato [, ANYTHING INSIDE QUOTE" Grapes - "-" Pineapple - -' 
perl -pe 's/ +(?=(([^"]*"){2})*[^"]*$)/|/g' <<< "$s" 
Apple|Mango|"Banana/Tomato [, ANYTHING INSIDE QUOTE"|Grapes|-|"-"|Pineapple|-|- 

此正則表達式使用一個超前僅如果有後跟偶數引號來匹配1個或多個空格(以確保空間之外引號),並取代他們通過管道。報價必須平衡。

1

根據定界符變化'[ ]+'(一個或多個空格)' '(只有一個空格)

use Text::ParseWords; 

local $" = "|"; 
while (<DATA>) { 
    chomp; 
    my @f = quotewords('[ ]+', 1, $_); 
    print "@f\n"; 
} 

__DATA__ 
Apple Mango "Banana/Tomato [, ANYTHING INSIDE QUOTE" Grapes - "-" Pineapple - - 

輸出

Apple|Mango|"Banana/Tomato [, ANYTHING INSIDE QUOTE"|Grapes|-|"-"|Pineapple|-|- 
1

寫這個詭計前,這是一個有點冗長:

 
#!/usr/bin/perl 

use strict; 
use warnings; 

sub splitOutput { 
    my $sep = ' '; 
    my $output = shift; 

    my @token_array =(); 

    while ($output) { 
    if ((substr ($output, 0, 1) eq "\"") && ($output =~ m/\"([^"]*)\"$sep?/)) { 
    push (@token_array, $1); 
    $output =~ s/\"[^"]*\"$sep?//; 
    } 
    elsif ($output =~ m/([^"$sep]*)$sep?/) { 
    push (@token_array, $1); 
    $output =~ s/[^"$sep]*$sep?//; 
    } 
    } 
    return @token_array; 
} 

my $string = <STDIN>; 

my @token_array = splitOutput ($string); 

print ("$string\n"); 
print (join ('|', @token_array),"\n"); 

這將替換ev中字符串中的匹配部分重複匹配下一個帶引號或不帶引號的字段。請注意,如果字段之間有兩個空格,則會將一個字段視爲空。結果字符串也被除去了引號。

相關問題