2012-05-09 246 views
2

所以这里有大量的帖子说明,而不是滚动我自己的csv解析器我应该使用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,伦敦,英国,地球”

我想要的是正则表达式返回引用\ escaped和数字的所有内容。

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

我非常感谢一些帮助,因为我正在尝试使用第三方库,但没有取得太大的成功。

不用说string.split在地址的情况下不起作用,并且http://www.filehelpers.com/似乎没有解释这样的例子。

+1

使用正则表达式解析CSV的确是很混乱的,特别是如果你不控制你的输入。所以除非你可以保证在字符串中不会有任何逃脱的引号,否则你将很难得到一个正则表达式来可靠地完成这项工作。 –

回答

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 
+0

谢谢Tim,我会试试看。 –

+0

\ * Noo-o-o,不是VB.NET!\ * 虽然你的答案很好。 – gaussblurinc

+0

@loldop:嘿,如果Joel Spolsky足够好,对我来说绝对够用:) –