【问题标题】:RegEx - Parse Csv Text正则表达式 - 解析 Csv 文本
【发布时间】:2012-05-18 00:09:42
【问题描述】:

所以这里有很多帖子说明我应该使用 Vb.Net TextFiledParser,而不是滚动我自己的 csv 解析器。

我试过了,如果我错了,请告诉我,它会根据单个分隔符进行解析。

所以如果我有一个地址字段“Flat 1, StackOverflow House, London”,我会得到三个字段。不幸的是,这不是我想要的。我需要给定单元格中的所有内容都保留为数组中的单个项目。

所以我开始编写自己的正则表达式如下:

var testString = @"""Test 1st string""" + "," + @"""Flat 1, StackOverflow House, London, England, The Earth""" + "," + "123456";

var matches = Regex.Matches(chars, @"""([^""\\])*?(?:\\.[^""\\]*)*?""");
var numbers = Regex.Matches(chars, @"\d+$");//only numbers
Assert.That(results.Count(), Is.EqualTo(3));
Assert.That(secondMatch.Count, Is.EqualTo(1));

第一个断言失败,因为没有返回字符串“123456”。该表达式仅返回“Test 1st string”和“Flat 1, StackOverflow House, London, England, The Earth”

我希望正则表达式返回所有引用\转义的内容和数字。

我不控制数据,但数字字符串都会被引用\转义,而数字不会。

我非常感谢一些帮助,因为我正在兜圈子尝试第三方库,但没有取得多大成功。

不用说 string.split 在地址的情况下不起作用,http://www.filehelpers.com/ 似乎没有考虑这些例子。

【问题讨论】:

  • 使用正则表达式解析 CSV 确实很麻烦,尤其是如果您不控制输入。因此,除非您可以保证字符串中不会有任何转义引号,否则您将很难让正则表达式可靠地完成这项工作。

标签: regex vb.net parsing csv


【解决方案1】:

我用来快速绕过它的一个 hacky 方法是首先用引号将 Split 括起来,然后在每个其他索引之间,去掉引号(或用某些东西替换它们)。然后Split再次在逗号上字符串

刚刚发现:Javascript code to parse CSV data - 我很欣赏它是 JavaScript 而不是 vb.net。不过,你应该可以关注它

还有How can I parse a CSV string with Javascript, which contains comma in data?

【讨论】:

    【解决方案2】:

    只是为了让您了解您遇到的问题:这是一个应该可以很好地工作的正则表达式。但是你肯定需要测试一下,因为 CSV 有很多极端情况,我肯定会错过一些(我假设逗号作为分隔符," 作为引号字符(即通过加倍逃脱)):

    (?:           # Match either
     (?>[^",\n]*) #  0 or more characters except comma, quote or newline
    |             # or
     "            #  an opening quote
     (?:          #  followed by either
      (?>[^"]*)   #   0 or more non-quote characters
     |            #  or
      ""          #   an escaped quote ("")
     )*           #  any number of times
     "            #  followed by a closing quote
    )             # End of alternation
    (?=,|$)       # Assert that the next character is a comma (or end of line)
    

    在 VB.NET 中:

    Dim ResultList As StringCollection = New StringCollection()
    Dim RegexObj As New Regex(
        "(?:            # Match either" & chr(10) & _
        " (?>[^"",\n]*) #  0 or more characters except comma, quote or newline" & chr(10) & _
        "|              # or" & chr(10) & _
        " ""            #  an opening quote" & chr(10) & _
        " (?:           #  followed by either" & chr(10) & _
        "  (?>[^""]*)   #   0 or more non-quote characters" & chr(10) & _
        " |             #  or" & chr(10) & _
        "  """"         #   an escaped quote ("""")" & chr(10) & _
        " )*            #  any number of times" & chr(10) & _
        " ""            #  followed by a closing quote" & chr(10) & _
        ")              # End of alternation" & chr(10) & _
        "(?=,|$)        # Assert that the next character is a comma (or end of line)", 
        RegexOptions.Multiline Or RegexOptions.IgnorePatternWhitespace)
    Dim MatchResult As Match = RegexObj.Match(SubjectString)
    While MatchResult.Success
        ResultList.Add(MatchResult.Value)
        MatchResult = MatchResult.NextMatch()
    End While
    

    【讨论】:

    • 谢谢蒂姆,我试试看。
    • @loldop:嘿,如果它对 Joel Spolsky 来说足够好,那对我来说绝对足够好 :)
    • @TimPietzcker 然而,这是我的看法,因为我在上周末花了太多时间在 VB(主要是 VBA)上编程:\。我之前说过,你的回答很好,是的:)而且我认为,作者应该更有礼貌并接受它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 2015-10-10
    • 1970-01-01
    相关资源
    最近更新 更多