регулярное выражение должно разделяться, которые содержатся вне двойных кавычек в файле CSV? - PullRequest
0 голосов
/ 21 октября 2009

Это образец

"abc","abcsds","adbc,ds","abc"

Вывод должен быть

abc
abcsds
adbc,ds
abc

Ответы [ 4 ]

0 голосов
/ 05 июня 2013

Этот ответ имеет решение C # для работы с CSV.

В частности, линия

private static Regex rexCsvSplitter = new Regex( @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))" );

содержит регулярное выражение, используемое для правильного разбиения, то есть с учетом цитирования и экранирования.

По сути, это совпадает с любой запятой, за которой следует четное количество кавычек (включая ноль). Это эффективно предотвращает сопоставление запятой, являющейся частью строки в кавычках, поскольку символ кавычки экранируется путем его удвоения.

Имейте в виду, что кавычки в приведенной выше строке удваиваются ради строкового литерала. Это выражение может быть проще представить как

,(?=(?:[^"]*"[^"]*")*(?![^"]*"))
0 голосов
/ 21 октября 2009

Это сложнее, чем вы думаете - не только могут быть запятые внутри кавычек, но также могут быть кавычки внутри кавычек. Две последовательные кавычки внутри строки в кавычках не означают конец строки. Вместо этого он сообщает кавычку, встроенную в строку, например:

"x", "y,""z"""

должен быть разобран как:

x
y,"z"

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

Find the first non-white-space character.
If it was a quote, read up to the next quote. Then read the next character.
    Repeat until that next character is not also a quote.
    If the next (non-whitespace) character is not a comma, input is malformed.
If it was not a quote, read up to the next comma.
Skip the comma, repeat the whole process for the next field.

Обратите внимание, что, несмотря на тег, я не предоставляю регулярное выражение - я совсем не уверен, что видел регулярное выражение, которое действительно может правильно обработать это.

0 голосов
/ 21 октября 2009

Если вы можете быть уверены, что нет внутренних, экранированных кавычек, тогда я думаю можно использовать регулярное выражение для этого. Однако большинство современных языков уже имеют надлежащие парсеры CSV.

Использование правильного парсера - правильный ответ на этот вопрос. Text::CSV для Perl, например.

Однако, если вы не можете использовать регулярные выражения, я бы посоветовал вам «позаимствовать» какой-то модуль, например, такой: http://metacpan.org/pod/Regexp::Common::balanced

0 голосов
/ 21 октября 2009

Попробуйте это:

"(.*?)"

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

Regex re = new Regex("\"(.*?)\"");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...