Изменение файла с разделителем канала на VB.net с разделителями-запятыми - PullRequest
0 голосов
/ 21 декабря 2018

Итак, у меня есть набор входов с разделителями каналов, которые выглядят примерно так:

"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, так что я не могу использовать его здесь (или я не способен). Если у кого-то есть идеи, это будет высоко ценится.

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018
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
0 голосов
/ 21 декабря 2018

Вот кодированная процедура, описанная в комментариях:

  • Прочитать все строки исходного входного файла,
  • исправить ошибочные строки (с помощью Regex или чего-либо еще, что подходит),
  • используйте TextFieldParser для выполнения анализа правильного ввода
  • Join() входных частей, созданных TextFieldParser с использованием , в качестве разделителя
  • saveисправленные, восстановленные строки ввода в окончательный выходной файл

Я использую Wiktor Stribiżew Шаблон регулярного выражения: похоже, он должен работать с учетом описания проблемы.

Примечание :
Конечно, я не знаю, следует ли использовать определенную кодировку.
Здесь кодировка используется по умолчанию 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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...