正则表达式在csv-parsing中以逗号分隔,在引号中忽略

时间:2014-06-17 21:39:13

标签: regex vb.net

所有 所以,我正在试图找出如何为Visual Basic.net制作一个简单的正则表达式代码,但我没有得到任何地方。

我正在将csv文件解析为数组列表,但源csv不是原始的。在足够的地方有额外的/流氓引用来使程序崩溃,并且有足够的引号集来手动修复数据很麻烦。

我写过一堆错误检查,大约有99.99%的时间可以正常工作。但是,对于每个文件夹解析10,000行,平均每组csv文件有一个错误。崩溃。为了使最后0.01%正确解析,我创建了一个If语句,它将拉出具有奇数引号的行并删除所有引号,这会触发手动错误检查如果没有引号,则字段处理为通常。如果引号数为偶数,则标准的Split函数不能忽略没有正则表达式的引号之间的分隔符。

有人可以帮我找出一个正则字符串,它会忽略用引号括起来的字段吗? 这是我到目前为止能够思考的代码。

提前谢谢

Using filereader1 As New Microsoft.VisualBasic.FileIO.TextFieldParser(files_(i),
              System.Text.Encoding.Default) 'system text decoding adds odd characters

    filereader1.TextFieldType = FieldType.Delimited
    'filereader1.Delimiters = New String() {","}
    filereader1.SetDelimiters(",") 
    filereader1.HasFieldsEnclosedInQuotes = True 


    For Each c As Char In whole_string
        If c = """" Then cnt = cnt + 1
    Next
    If cnt = 0 Then 'no quotes
        split_string = Split(whole_string, ",") 'split by commas
    ElseIf cnt Mod 2 = 0 Then 'even number of quotes

         split_string = Regex.Split(whole_string, "(?=(([^""]|.)*""([^""]|.)*"")*([^""]|.)*$)")
    ElseIf cnt <> 0 Then 'odd number of quotes
        whole_string = whole_string.Replace("""", " ") 'delete all quotes
        split_string = Split(whole_string, ",") 'split by commas
    End If

1 个答案:

答案 0 :(得分:2)

在VB.NET中,有几种方法可以继续。

选项1

您可以使用此正则表达式:,(?![^",]*")

它匹配不在引号内的逗号:后跟的逗号,(由负向前瞻(?![^",]*")声明)由不是逗号的字符组成也不引用引用。

在VB.NET中,类似于:

Dim MyRegex As New Regex(",(?![^"",]*"")")
ResultString = MyRegex.Replace(Subject, "|")

选项2

这使用了这个非常简单的正则表达式:"[^"]*"|(,)

这是一个更通用的解决方案,易于调整解决方案。有关完整说明,建议您查看有关Regex-matching or replacing... except when...的问题。如果您发现其他情况需要调整,它可以提供一个非常整洁的解决方案,易于维护。

交替|的左侧匹配完成"quotes"。我们将忽略这些匹配。右侧匹配并捕获第1组的逗号,我们知道它们是正确的,因为它们与左侧的表达式不匹配。

此代码应该有效:

Imports System
Imports System.Text.RegularExpressions
Imports System.Collections.Specialized

Module Module1
Sub Main()
Dim MyRegex As New Regex("""[^""]*""|(,)")
Dim Subject As String = "LIST,410210,2-4,""PUMP, HYDRAULIC PISTON - MAIN"",1,,,"
Dim Replaced As String = myRegex.Replace(Subject, 
                     Function(m As Match)
                        If (m.Groups(1).Value = "") Then
                            Return ""
                        Else 
                            Return m.Groups(0).Value
                        End If
                     End Function)
Console.WriteLine(Replaced)

Console.WriteLine(vbCrLf & "Press Any Key to Exit.")
Console.ReadKey()
End Sub
End Module

参考