2016-06-27 55 views
5

我遇到了一些問題,試圖從一些文件中的某些貨幣值中提取數千個分隔符。 「壞」值用逗號和雙引號分隔。在那裏有其他值是< $ 1000沒有問題。現有文件的使用正則表達式替換csv中的千位分隔符

示例:

實施例的
"12,345.67",12.34,"123,456.78",1.00,"123,456,789.12" 

期望文件(已刪除千位分隔符):

"12345.67",12.34,"123456.78",1.00,"123456789.12" 

我發現了一個正則表達式的表達式的數字與該工作很大隔板匹配,但是我在替換運算符時遇到了問題。重置價值讓我感到困惑。我讀了約$ &,我想知道我是否應該在這裏使用。我嘗試了$ _,但是這會拉出所有我的逗號。我是否必須以某種方式使用$匹配?

這裏是我的代碼:

$Files = Get-ChildItem *input.csv 
foreach ($file in $Files) 
    { 
     $file | 
     Get-Content | #assume that I can't use -raw 
     % {$_ -replace '"[\d]{1,3}(,[\d]{3})*(\.[\d]+)?"', ("$&" -replace ',','')} | #this is my problem 
     out-file output.csv -append -encoding ascii 
    } 
+2

使用import-csv,然後你可以循環遍歷行和項目,從每個項目中刪除逗號,同時構建新行,然後將新行保存到覆蓋它的文件中。 –

回答

3

你可以用這個表達式嘗試:

,(?=(\d{3},?)+(?:\.\d{1,3})?") 

Live Demo或在PowerShell中:

% {$_ -replace ',(?=(\d{3},?)+(?:\.\d{1,3})?")','' } 

但它更多的是該正則表達式可以帶來的挑戰。爲了正確的工作,使用@briantist答案,這是乾淨的方式來做到這一點。

+0

這就像一個CHAMP一樣,促使我閱讀更多關於「積極主張」和「先行組織」等內容。謝謝托馬斯。 – astraljack

2

我會用一個簡單的正則表達式,並使用捕獲組而不是整個捕獲的。 我已經用您的輸入測試了下面的正則表達式,發現沒有問題。

% {$_ -replace '([\d]),([\d])','$1$2' }

如。在之前和之後查找所有帶有數字的逗號(以便奇怪的混合分割不重要)並完全替換逗號。

如果您的輸入有一個沒有奇怪的混合引號和沒有引號的場景,這會有問題。

+1

我個人喜歡這個答案。您可以直接將文件導入爲文本,運行正則表達式替換,並將其輸出爲文本。不需要將事物轉換爲對象,所以它應該減少開銷。你甚至可以把它看成是一個前瞻/後視,並跳過替換的最後一部分。 [RegEx101示例](https:// regex101。com/r/nL2rM9/2) – TheMadTechnician

+1

這也很棒。我認爲它會失敗與多個分隔符(例如123,456,789.12),但它的工作,現在我明白了爲什麼。 – astraljack

5

Tony Hinkle的評論是答案:不要使用正則表達式(至少不直接在CSV文件上)。

您的CSV文件是有效的,因此您應該對它進行解析,處理對象(如果需要更改文本),然後編寫新的CSV文件。

Import-Csv -Path .\my.csv | ForEach-Object { 
    $_ | ForEach-Object { 
     $_ -replace ',','' 
    } 
} | Export-Csv -Path .\my_new.csv 

(此代碼需要的工作,特別是中間的一行將每列的屬性,而不是一個數組,但你的CSV更完整的版本會提出這樣更容易證明)