Как обнаружить квалификаторы текста в плоском файле (CSV, TSV и т. д.)?

Мы получаем файлы в различных форматах — CSV, TSV или другие плоские файлы, использующие более экзотические разделители (|, ; и т. д.). В этих файлах также могут использоваться текстовые квалификаторы, опять же в различных форматах (каждое поле квалифицировано против только тех, которые содержат квалифицированный разделитель, используются разные символы ', " и т. д.).

Я написал инструмент, который может успешно идентифицировать разделители в файле, используя метод частотного анализа, мало чем отличающийся от класса сниффера Python, упомянутого здесь: Как определить, какой разделитель используется в текстовом файле?

Сейчас я пытаюсь расширить инструмент для поддержки текстовых файлов. Трудность здесь заключается в том, что частотного анализа недостаточно для определения текстовых квалификаторов, так как многие формы CSV будут только оборачивать поля, содержащие разделитель, текстовыми квалификаторами, поэтому, например, файл с 10 000 строк может иметь только 2 вхождения текстового квалификатора в целом. файл.

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

Может ли кто-нибудь предложить более надежную альтернативу? Ключевым ограничением проблемы является то, что я должен поддерживать файлы в любом из множества различных вариантов CSV, которые могут быть созданы. Моя цель — поддерживать как можно больше случаев без вмешательства пользователя.


person Root_Kabal    schedule 28.05.2013    source источник


Ответы (2)


Вы можете попробовать сопоставление с образцом с помощью регулярных выражений. Поскольку вы уже знаете разделитель, вы можете попробовать список общих квалификаторов, таких как " или '. Если это не удается, вы можете попытаться проанализировать строки с неправильным выравниванием столбцов для входных данных, которые будут соответствовать шаблону и произвести ожидаемое выравнивание столбцов.

var delimiter = ",";
var qualifiers = new[] { "\"", "'" };
var input = @"""Hello, World"", Hello, World";
var pattern = @"(?<={1}).*{0}.*(?={1})";

foreach(var p in qualifiers.Select(q => string.Format(pattern, delimiter, q)))
{
    Regex.Match(input, p);
}
person Dustin Kingen    schedule 28.05.2013
comment
Спасибо, я буду изучать это дальше. Я думал, что Regex может быть подходящим способом, но изо всех сил пытался придумать правильное выражение, поскольку нужно рассмотреть несколько случаев - если первое поле является текстовым, это будет..., например, а не ,.. ., и это переворачивается для конечного поля с текстом. Ваш ответ может быть просто трамплином, который мне нужен. - person Root_Kabal; 30.05.2013

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

person Amit    schedule 28.05.2013