#Region Inline Data Capture 'Collapsing regions is a good way to hide auxilliary code
Sub InlineData As List
Dim data As String = $"
______
field1, field2, field3, field4
1,2,"a,b,c"
4,${Chr(13)}
6,"d""ef",8,9
______
"$
Return parseCVS(data)
End Sub
Sub parseCVS(s As String) As List
'There are other solutions for doing this - this "state machine" is simpler than using regular expression
Dim workingArea As StringBuilder: workingArea.Initialize
Dim result As List: result.Initialize
Dim lastRow As List: lastRow.Initialize
result.Add(lastRow)
Dim maxLineLength As Int = -1
Dim skipNext As Boolean = False
Dim inQuote As Boolean = False
Dim prevChar As String = s.CharAt(0)
Dim currentChar As String
For i = 1 To s.Length - 1
currentChar = s.CharAt(i)
If skipNext Then
skipNext = False
Else
If inQuote Then
If prevChar = QUOTE And currentChar = QUOTE Then
workingArea.Append(QUOTE)
skipNext = True
Else if prevChar = QUOTE Then
inQuote = False
Else
workingArea.append(prevChar)
End If
Else if prevChar = QUOTE Then
inQuote = True
Else
If prevChar = "," Or prevChar = TAB Then
lastRow.Add(workingArea.toString)
workingArea.Initialize
Else If prevChar = Chr(13) Or prevChar = Chr(10) Then
lastRow.Add(workingArea.toString)
If lastRow.Size > maxLineLength Then maxLineLength = lastRow.Size
Dim lastRow As List: lastRow.Initialize
result.Add(lastRow)
workingArea.Initialize
If currentChar = Chr(13) Or currentChar = Chr(10) Then skipNext = True
Else
workingArea.append(prevChar)
End If
End If
End If
prevChar = currentChar
Next
workingArea.append(currentChar)
lastRow.Add(workingArea.toString)
'This section will extract the actual data and normalize the lines to string arrays of the same max line length
Dim actualData As Boolean = False
Dim cleanResult As List: cleanResult.Initialize
For Each line As List In result
If line.Size>0 Then
Dim firstItem As String = line.get(0)
If actualData = False And firstItem.startsWith("____") Then
actualData = True
Else if firstItem.startsWith("____") Then
actualData = False
Else if actualData Then
Dim w(maxLineLength) As String
For j = 0 To line.size - 1
w(j) = line.Get(j)
Next
cleanResult.Add(w)
End If
End If
Next
Return cleanResult
End Sub
#End Region