2012-05-09 2 views
2

Значит, здесь есть много сообщений, которые напоминают, а не катят мой собственный синтаксический анализатор csv. Я должен использовать либо VB.Net TextFiledParser.RegEx - Parse Csv Text

Я попробовал, но, пожалуйста, скажите мне, если я ошибаюсь, он будет разбирать на основе одного делиметра.

Итак, если у меня есть поле адреса «Flat 1, StackOverflow House, London», я получаю три поля. К сожалению, это не то, что я хочу. Мне нужно, чтобы все в данной ячейке оставалось одним элементом в массиве.

Так что я начал писать свой собственный RegEx следующим образом:

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/, похоже, не учитывает такие примеры.

+1

Использование регулярных выражений для разбора CSV действительно очень грязный, особенно если вы не контролируете свой вход. Поэтому, если вы не можете гарантировать, что в строках не будет никаких скрытых кавычек, вам будет очень сложно получить регулярное выражение, чтобы сделать эту работу надежно. –

ответ

0

Хакерный способ, которым я использовал, чтобы быстро обойти его, был первым 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 
+0

Спасибо, Тим, я попробую. –

+0

\ * Noo-o-o, а не VB.NET! \ * Хотя ваш ответ хороший. – gaussblurinc

+0

@loldop: Эй, если это достаточно для Джоэла Спольски, это определенно достаточно для меня :) –