比糖蜜慢,但經歷二十年拼湊十幾個或更多後部分解決方案,我決定明確解決它。當然,隨着時間的推移,各種解析器庫現在都可用。
function SplitDelim($Line, $Delim=",", $Default=$Null, $Size=$Null) {
# 4956968,"""Visible,"" 4D ""Human"" Torso Anatomy Kit (4-5/8)",FDV-26051,"" ,"",,,,,,a
# "4956968,"""Visible,"" 4D ""Human"" Torso Anatomy Kit (4-5/8)",FDV-26051,"" ,"",,,,,,a
# ,4956968,"""Visible,"" 4D ""Human"" Torso Anatomy Kit (4-5/8)",FDV-26051,"" ,"",,,,,,a
$Field = ""
$Fields = @()
$Quotes = 0
$State = 'INF' # INFIELD, INQFIELD, NOFIELD
$NextState = $Null
for ($i=0; $i -lt $Line.length; $i++) {
$Char = $Line.substring($i,1)
if($State -eq 'NOF') {
# NOF and Char is Quote
# NextState becomes INQ
if ($Char -eq '"') {
$NextState = 'INQ'
}
# NOF and Char is Delim
# NextState becomes NOF
elseif ($Char -eq $Delim) {
$NextState = 'NOF'
$Char = $Null
}
# NOF and Char is not Delim, Quote or space
# NextState becomes INF
elseif ($Char -ne " ") {
$NextState = 'INF'
}
} elseif ($State -eq 'INF') {
# INF and Char is Quote
# Error
if ($Char -eq '"') {
return $Null}
# INF and Char is Delim
# NextState Becomes NOF
elseif ($Char -eq $Delim) {
$NextState = 'NOF'
$Char = $Null
}
} elseif ($State -eq 'INQ') {
# INQ and Char is Delim and consecutive Quotes mod 2 is 0
# NextState is NOF
if ($Char -eq $Delim -and $Quotes % 2 -eq 0) {
$NextState = 'NOF'
$Char = $Null
}
}
# Track consecutive quote for purposes of mod 2 logic
if ($Char -eq '"') {
$Quotes++
} elseif ($NextState -eq 'INQ') {
$Quotes = 0
}
# Normal duty
if ($State -ne 'NOF' -or $NextState -ne 'NOF') {
$Field += $Char
}
# Push to $Fields and clear
if ($NextState -eq 'NOF') {
$Fields += (IfBlank $Field $Default)
$Field = ''
}
if ($NextState) {
$State = $NextState
$NextState = $Null
}
}
$Fields += (IfNull $Field $Default)
while ($Size -and $Fields.count -lt $Size) {
$Fields += $Default
}
return $Fields
}
請不要使用正則表達式解析CSV。 :)這是對人類的犯罪。 – Josh 2010-09-17 07:08:48