所以我有一组用管道分隔的输入,如下所示:
“ 787291 | 3224325523” | 37826427 | 2482472 | “ 46284729 | 46246” | 24682 | 82524 | 6846419 | 68247
我正在使用下面给出的代码将它们转换为逗号分隔:
Dim line As String
Dim fields As String()
Using sw As New StreamWriter("c:\test\output.txt")
Using tfp As New FileIO.TextFieldParser("c:\test\test.txt")
tfp.TextFieldType = FileIO.FieldType.Delimited
tfp.Delimiters = New String() {"|"}
tfp.HasFieldsEnclosedInQuotes = True
While Not tfp.EndOfData
fields = tfp.ReadFields
line = String.Join(",", fields)
sw.WriteLine(line)
End While
End Using
End Using
到目前为止,一切都很好。它仅考虑引号外的定界符,并将其更改为逗号定界符。但是,当我输入以下引号引起麻烦时:
“ 787291 | 3224325523” | 37826427 | 2482472 | “ 46284729 | 46246” | 24682 | “ 82524 | 6846419 | 68247
代码在此处提供
MalformeLineExcpetion
我意识到这是由于输入中的引号引起的,并且由于我就像RegEx中的一个菜鸟,所以我不能在这里使用它(或者我无法使用)。如果有人有任何想法,将不胜感激。
答案 0 :(得分:1)
这是注释中描述的编码过程:
TextFieldParser
来解析正确的输入Join()
由TextFieldParser
使用,
作为分隔符创建的输入部分我正在使用Wiktor Stribiżew正则表达式模式:给出问题描述后,它应该可以工作。
注意:
当然,我不知道是否应该使用特定的编码。
在这里,Encoding is the default UTF-8 no-BOM
进进出出。
"FaultyInput.txt"
是损坏的源文件。
"FixedInput.txt"
是包含正则表达式固定(希望)的输入行的文件。您也可以使用MemoryStream
。
"FixedOutput.txt"
是最终的CSV
文件,其中包含逗号分隔的字段和正确的值。
这些文件都是在可执行启动路径中读取/写入的。
Dim input As List(Of String) = File.ReadAllLines("FaultyInput.txt").ToList()
For line As Integer = 0 To input.Count - 1
input(line) = Regex.Replace(input(line), "(""\b.*?\b"")|""", "$1")
Next
File.WriteAllLines("FixedInput.txt", input)
Dim output As List(Of String) = New List(Of String)
Using tfp As New FileIO.TextFieldParser("FixedInput.txt")
tfp.TextFieldType = FileIO.FieldType.Delimited
tfp.Delimiters = New String() {"|"}
tfp.HasFieldsEnclosedInQuotes = True
While Not tfp.EndOfData
Dim fields As String() = tfp.ReadFields
output.Add(String.Join(",", fields))
End While
End Using
File.WriteAllLines("FixedOutput.txt", output)
'Eventually...
'File.Delete("FixedInput.txt")
答案 1 :(得分:1)
Sub ReadMalformedCSV()
Dim s$
Dim pattern$ = "(?x)" + vbCrLf +
"\b #word boundary" + vbCrLf +
"(?'num'\d+) #any number of digits" + vbCrLf +
"\b #word boundary"
'// Use "ReadLines" as it will lazily read one line at time
For Each line In File.ReadLines("c:\test\output.txt")
s = String.Join(",", Regex.Matches(line, pattern).
Select(Function(e) e.Groups("num").Value))
WriteLine(s)
Next
End Sub