如何像:
$subject = 'ITEM1 Quantity: 12x 355ml bottlePrice: $23.95 $23.50 SAVE $0.45'
if ($subject -cmatch '^(?<Name>.*)Quantity:(?<Quantity>.*)x(?<Size>.*)bottle\s*Price:(?<OrigPrice>.*)\s*(?<SalePrice>\$.*)SAVE(?<Savings>.*)$') {
$result = $matches[0]
} else {
$result = ''
}
"Matches:"
$matches
我不知道是否有真正需要的是一瓶&價格之間的空間(它看起來並不像它,但如果它會處理它是)。
如果您需要的名稱,您可以訪問它想:
$matches["Name"]
更好的解決方案(和一個實際上它得到CSV格式,會像以下(感謝@nickptrvc指點什麼我錯過了):
function Read-Data {
[cmdletbinding()]
param(
[parameter(Mandatory)][string]$Path
)
$reader = [System.IO.File]::OpenText($Path)
while(($subject = $reader.ReadLine()) -ne $null) {
if ($subject -cmatch '^(?<Name>.*)Quantity:(?<Quantity>.*)x(?<Size>.*)bottle\s*Price:(?<OrigPrice>.*)\s*(?<SalePrice>\$.*)SAVE(?<Savings>.*)$') {
$result = $matches[0]
$obj = [PSCustomObject]@{
Name=$matches["Name"].trim();
Quantity=$matches["Quantity"].trim();
Size=$matches["Size"].trim();
OrigPrice=$matches["OrigPrice"].Trim();
SalePrice=$matches["SalePrice"].Trim();
Savings=$matches["Savings"].Trim()
}
$obj
}
}
}
然後,要使用它,這個保存到一個文件(我打電話給我讀Data.ps1),源文件,然後你有兩個選擇:1)你可以使用ConvertTo-Csv
將對象簡單地轉換爲CSV,並將結果返回到屏幕,或者喲ü可以使用Export-Csv
將其保存到一個文件:
. C:\Test\Convert-Data.ps1
Read-Data -Path C:\Test\datafile.dat | ConvertTo-Csv -NoTypeInformation
或
Read-Data -Path C:\Test\datafile.dat | Export-Csv -NoTypeInformation -Path C:\Test\datafile.csv
要獲得CSV結果,你可以在if塊的真正範圍添加此。該命令將按鍵名按字母順序排列,在這種情況下爲正則表達式組名,例如名稱,數量等... 'if(...){ $ matches.remove(0) $ result =($ matches.values |%{$ _。修改()})-join',' } } else { ... }' – nickptrvc
感謝@nickptrvc,有點讓我印象深刻的正規表達式,我忘了回答問題的其餘部分... :)我更新了我的答案w /一個函數,返回一個適合於Export-Csv和ConvertTo-Csv的對象... –
我也對正則表達式留下了深刻的印象!我會說,我建議這個片段,因爲它不需要用戶輸入像$ matches ['Size']這樣的鍵名,使它更具動態性(當然,正則表達式約束)。 我絕對喜歡PSCustomObject類型的想法,但用戶必須使用版本3才能創建這些類型。在版本2中,使用PSObject非常慢。所以在這種情況下,我通常默認只使用散列表並連接字符串。最大的優勢是向後兼容性從3到2. – nickptrvc