2012-05-10 54 views
0

假設我要分析的文件裏面領域引號字符分析字符串

 
$ cat toParse.txt 
1 2 3 4 5 
1 "2 3" 4 5 
1 2" 3 " 4 5 

前兩行很容易解析:Text::CSV可以處理它。舉例來說,我想:

 
use strict; 
use Text::CSV; 
while() { 
    chomp $_; 
    my $csv = Text::CSV->new({ sep_char => ' ', quote_char => '"' , binary => 1}); 
    $csv->parse($_); 
    my @fields = $csv->fields(); 
    my $badArg = $csv->error_input(); 
    print "fields[1] = $fields[1]\n"; 
    print "Bad argument: $badArg\n\n"; 
} 

但是,如果報價字符內標記化領域包含CSV變得非常混亂。

上述程序打印出:

 
fields[1] = 2 
Bad argument: 

fields[1] = 2 3 
Bad argument: 

fields[1] = 
Bad argument: 1 2" 3 " 4 5 

有沒有人有什麼建議?我想最後的fields[1]填充2" 3 " ...換句話說,我想分割行中不包含在引用字符串中的任何空格。

+0

我想在空格字符'「」'上分隔每一行,每當引號字符串中不包含空格時。 – asf107

+0

我認爲'allow_loose_quotes => 1'會做到這一點。 – ikegami

+0

'allow_loose_quotes => 1'絕對有幫助,但是如果在鬆散引號內有一個'sep_char',解析器仍然會中斷。 – asf107

回答

1

你想要的不是CSV,所以你需要編碼你自己的解析。

這應該爲您的特定情況下工作:

use strict; 

while (<DATA>) { 
    chomp $_; 
    my @fields = /([^\s"]+|(?:[^\s"]*"[^"]*"[^\s"]*)+)(?:\s|$)/g; 
    print "$_\n" for @fields; 
    print "\n"; 
} 

__DATA__ 

1 2 3 4 5 
1 "2 3" 4 5 
1 2" 3 " 4 5 
1 2" 3 "4 5 
1 2" 3 "4" 5" 6 
1 2" 3 "4"" 5"" 6 

...,其輸出是:

1 
2 
3 
4 
5 

1 
"2 3" 
4 
5 

1 
2" 3 " 
4 
5 

1 
2" 3 "4 
5 

1 
2" 3 "4" 5" 
6 

1 
2" 3 "4"" 
5"" 
6 

點擊here進行測試。

+0

thanks。我一直在使用reg-ex來解析(看起來像這樣的數據),我想我想知道是否有更清晰的方法去做吧。 – asf107

0

變化quote_char到其它的東西,「和第三行是

1 
2" 
3 
" 
4 
5 

但是第二行現在將

1 
"2 
3" 
4 
5 

所以,你似乎有一條線在那裏」是引號分隔符,還有一個不是。

因此,您正在解析的文件已損壞,您將不得不變得聰明起來。

+0

我想爲所有三行使用''''引號分隔符,這將使我所需的輸出如下所示: 'fields [1] = 2','fields [1] = 2 3'和'字段[1] = 2「3」'分別爲 – asf107

+0

Eh 2「3」不會發生想象如果字段分隔符是逗號 –

+0

爲了說明導致解析器的困難,使用'Then 1'的引號分隔符2 3'4 and 1'2「3」'4 would work。 –