2012-05-04 66 views
3

我從CSV文件中獲得一行,其中"作爲字段封閉器,,作爲字段分隔符作爲字符串。有時在打破字段外殼程序的數據中有"。我正在尋找一個正則表達式來刪除這些"Perl正則表達式:如何從CSV行中刪除引號內的引號

我的字符串如下所示:

my $csv = qq~"123456","024003","Stuff","","28" stuff with more stuff","2"," 1.99 ","",""~; 

我看了this但我不知道如何告訴它:只可以卸下

  1. 沒有之初報價字符串
  2. 不在字符串的末尾
  3. 之前沒有,
  4. 後面沒有,

我設法告訴它同時具有這行代碼刪除3和4:

$csv =~ s/(?<!,)"(?!,)//g; 

不過,我不適合在那裏^$因爲向前看和向後看都不喜歡寫成(?<!(^|,))

有沒有辦法實現這一點,除了分割字符串和刪除每個元素的引號之外的正則表達式?

+2

有兩種CSV正則表達式:那些現在失敗和那些將失敗的CSV正則表達式。 –

回答

1

這應該工作:

$csv =~ s/(?<=[^,])"(?=[^,])//g 

12意味着必須有至少一個字符之前和逗號之後,因此積極lookarounds。 34意味着這些字符可以是逗號以外的任何字符。

+0

主席先生,你是一位天才。 :D謝謝。 – simbabque

+0

@simbabque:樂於幫助。 – flesk

+0

它也將刪除尾部報價。即。 「abc」,「def」變成了「abc」,「def」,所以我沒有在新行的後面添加/(?<= [^,])「(?= [^,)])(?!$) // g' – Interlated

10

操縱CSV數據我reccomend使用Text::CSV - 有內CSV數據,這雖然有可能去構造的代碼來處理自己很多潛在的複雜性,是不值得的努力時,有一個久經考驗的CPAN模塊爲你做

+1

我知道,但我只想刪除報價,我不對數據做任何其他事情。這更像是查看工作原理的一般問題。 – simbabque

+1

+1 for Text :: CSV –

+3

除非您純粹將此視爲正則表達式的學習練習,否則您在某些時候會被CSV數據中的意外格式化(即未由您的正則表達式處理)咬傷。我自己忽視了這個建議,並且學會了艱難的道路! – beresfordt

4

不要使用正則表達式解析CSV文件,CPAN提供了很多很好的模塊,如爲nickifat建議,使用Text::CSV也可以使用Text::ParseWords

use Text::ParseWords; 
while (<DATA>) { 
chomp;  
my @f = quotewords ',', 0, $_;  
print join "|" => @f; 
} 

__DATA__ 
"123456","024003","Stuff","",""28" stuff with more stuff","2"," 1.99 ","","" 

輸出:

123456|024003|Stuff||28 stuff with more stuff|2| 1.99 || 
+1

感謝您的輸入。我不知道「Text :: ParseWords」,它看起來很有幫助。但是,我不打算使用CSV文件中的數據。我只想刪除文字內的引號。我既不建立CSV也不讀取它。我只是清理已經看起來像CSV文件的數據,然後去其他地方。 – simbabque

-1

建議

$csv =~ s/(?<=[^,])"(?=[^,])//g; 

可能是最好的答案。如果沒有這些先進的正則表達式的功能,你也可以做同樣的

$csv =~ s/([^,])"([^,])/$1$2/g; 

$csv = join (',', map {s/"//g;"\"$_\""} split (',', $csv)); 

我想你應該知道,你的字符串沒有很好地格式化CSV。在csv文件中,值內的雙引號必須加倍(http://en.wikipedia.org/wiki/Comma-separated_values)。使用您的格式,值不能在逗號附近包含引號。

csv是一個不那麼簡單的格式。如果你決定使用「真正的」csv,你應該使用一個模塊。 否則,您應該刪除所有的雙引號,以簡化您的代碼並澄清您沒有執行csv。

+0

他們不一樣。 #2不連續處理兩個引號。 #3更糟糕,用逗號分成兩部分。 – ikegami

0

感謝您的幫助。我在嵌入雙引號時遇到格式不正確的CSV問題。我會做一個輕微除了在線路末端的正則表達式,否則空值的先行部分將被破壞:

(?<=[^,])\"(?=[^,\n]) 

添加\ n將在最終消除對最後一個雙引號匹配的線。

相關問題