2011-06-22 69 views
0

可能重複:
How can I parse quoted CSV in Perl with a regex?簡單的Perl分裂()和正則表達式的問題

我試圖採取一個CSV文件導入每一行到一個數組(其中每個元素代表一列)。一個CSV文件的格式很簡單:

item1,item2,item3 
nextrowitem1,item2,item3 
"items,with,commas","are,in,quotes" 

我進口使用CSV文件:

open(FILE, "test.csv"); 
@lines = <FILE>; 

然後,我通過它使用循環:

foreach(@lines){ 
    @items = split(/regular expression/); 
    /*Do stuff with @items array*/ 
} 

(請注意,你做不需要使用split(/regular expression, $string);,因爲split()假設爲$_,如果沒有字符串提供)

在我使用CSV文件測試文件之前,其中沒有任何項目包含逗號和split(/,/)的簡單正則表達式。這工作得很好,所以在正則表達式之後,文件,讀取或循環都沒有問題。然而,當我打包含一個逗號的項目他們也有可以理解的劃分,像這樣:

1 => "items 
2 => with 
3 => commas" 
4 => "are 
5 => in 
6 => quotes" 

代替所需的:

1 => items,with,commas 
2 => are,in,quotes 

誰能幫我制定一個正則表達式正確拆分這陣?基本上,如果該項目以報價(")開頭,則需要等到","才能拆分。如果該項目沒有以報價開始,則需要等到,才能分拆。

+1

謝謝你鏈接到那=)肯定是重複的 - 事實上,他的問題比我的更詳細。我現在將看看CPAN,看看我是否可以利用它。 – stevendesu

回答

5

嘗試閱讀Text::CSV作爲已經這樣做的可能選項。將CSV解析爲正則表達式的問題在於,您必須查找","(您指出)以及,間隔。

+0

我同意。您不能使用正則表達式進行CVS分割,因爲逗號和引號可以位於CVS字段中。唯一真正的方法是在一個循環中逐行分解這一行。 Text :: CVS爲你創造了奇蹟。 –

+0

@David,[CVS](http://en.wikipedia.org/wiki/Concurrent_Versions_System)和[CSV](http://en.wikipedia.org/wiki/Comma-separated_values)大不相同。 – cjm

+0

是的,我知道。不幸的是,我有誦讀困難症,並且正在與使用CVS的項目合作。混亂必然會發生。我的意思是「CSV」。 –

5

只需使用Text::CSV_XS,而不是...

+0

或者使用[Text :: CSV](http://search.cpan.org/perldoc?Text::CSV),如果速度可以使用Text :: CSV_XS,但也可以使用純Perl實現你沒有一個C編譯器。 – cjm

-1

見我post that solves this problem更多細節。

^(?:(?:"((?:""|[^"])+)"|([^,]*))(?:$|,))+$將匹配整行,然後您可以使用匹配的捕獲來獲取您的數據(不帶引號)。

+0

當表達式以問號開頭時,這意味着什麼?我知道'^ ab?'會匹配'a'或'ab',但'^(?:....''的意義是什麼?我從來沒有在開頭看過問號...... – stevendesu

+0

This是CSV模塊的一個工作,正如其他答案所建議的,而不是正則表達式 – justintime

+0

'(?:expression)'表示一個非捕獲組,這阻止了正則表達式引擎跟蹤匹配該表達式部分的字符串部分。在$ 1,$ 2,$ 3等在這裏:http://www.regular-expressions.info/perl.html –