ограничивающий формат

Кажется, я не могу найти это нигде в stackoverflow, поэтому вот оно:

У меня есть файл, я хочу узнать, разделяется ли он вертикальной чертой (|) или запятой (,). Я также хочу сказать, является ли квалификатор текста кавычкой (") или ничем. У кого-нибудь есть какие-либо функции C #, которые делают это? Спасибо!


person Badmiral    schedule 07.05.2012    source источник
comment
Узнайте, какой разделитель используется? Какую эвристику вы имели в виду?   -  person Oded    schedule 07.05.2012
comment
В основном выполните поиск по строке и попытайтесь проанализировать ее и поместить разделитель в какой-либо символ или строку.   -  person Badmiral    schedule 07.05.2012
comment
Знаете ли вы что-нибудь о данных, например о количестве элементов в строке?   -  person Servy    schedule 07.05.2012
comment
Вы имеете в виду для любого произвольного файла? Что вы знаете об этих файлах?   -  person Oded    schedule 07.05.2012
comment
Выберите разделитель и подсчитайте, сколько раз он встречается в значительном количестве строк. Если он всегда встречается столько же раз, сколько и количество столбцов, вероятно, это ваш разделитель. Если другой разделитель дает тот же результат, вы облажались. Если ни один разделитель не дает такого результата, вам нужно применить больше предположений.   -  person Igby Largeman    schedule 07.05.2012


Ответы (3)


Для таких файлов с текстовым разделением я нахожу TextFieldParser быть очень полезным инструментом. (Вы можете импортировать визуальную базовую dll, чтобы использовать ее в приложении C#).

Общая стратегия, которую я бы использовал, поскольку, по вашему мнению, в файле есть фиксированное количество столбцов, заключалась бы в том, чтобы выбрать разделитель и продолжить синтаксический анализ/чтение строк до тех пор, пока одна строка не будет иметь другое количество столбцов, чем предыдущая строка. Когда это произойдет, переключитесь на другой разделитель (не уверен, что вы хотите сделать, если оба недействительны). Вы также можете выбросить разделитель, если он вообще не найден в первой строке. Использование TextFieldParser с параметром HasFieldEnclosedInQuotes, равным true, вы можете правильно обрабатывать поля, заключенные в кавычки (он все равно будет работать нормально, если кавычки не используются). Это будет намного проще, чем пытаться вручную обрабатывать кавычки при использовании обычных операций со строками.

person Servy    schedule 07.05.2012

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

char[] delims = { '|', ',', ... };

Возьмите подмножество строк или весь файл, если он достаточно мал, и сохраните их в массиве строк.

string[] lines = text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

Прокрутите разделители, вставив количество разделенных записей, используя этот разделитель, в массив целых чисел:

int[] counts = lines.Select(s => s.Split(currentDelimiter).Length).ToArray();

Используйте свой собственный метод, чтобы убедиться, что все счетчики равны друг другу и все больше 1. Используйте разделитель, на котором вы находитесь.

person Derreck Dean    schedule 07.05.2012
comment
Там слишком много предположений. ОП не предоставил почти достаточно подробностей для формулировки ответа - только догадки. - person Oded; 07.05.2012
comment
Многие списки, разделенные запятыми/вертикальными чертами, не будут иметь одинаковое количество элементов в каждой строке, и вам также необходимо учитывать тот факт, что некоторые разделители могут находиться внутри строковых квалификаторов, что будет проблемой для вашего подсчета. - person Servy; 07.05.2012
comment
Хороший вопрос, @Servy. Это может быть дубликат stackoverflow.com/questions/761932/ - person Derreck Dean; 07.05.2012

Получить первую (или вторую строку, если первая — заголовок с именами файлов).

Затем вы можете использовать регулярное выражение для проверки возможных форматов. то есть

 Regex rePipesAndQualifier = ("[^|"]*"|);

Если rePipesAndQualifier.match(yourFileLine); возвращает несколько непустых совпадений, то вы знаете, что он использует конвейеры в качестве разделителей и имеет разделители.

Сделайте еще несколько регулярных выражений, чтобы проверить наличие запятых с разделителями, а также с квалификатором и без него.

Это немного зависит от того, что вы ожидаете получить (все с разделителями, только с разделителями строк) и что вы знаете (разделители в начале и в конце или только в середине, количество полей и т. д.). Поэтому я не могу дать вам точное решение.

person JotaBe    schedule 07.05.2012
comment
Файл с разделителями-контурами может иметь поля с запятыми, а файл с разделителями-запятыми может иметь поля с конвейерами. Существование одного из них ничего вам не говорит. - person Servy; 07.05.2012
comment
если может быть смесь всего, и у вас нет дополнительной информации, используйте хрустальный шар. Серьезно, должно быть что-то, что вы знаете заранее. - person JotaBe; 07.05.2012
comment
Да, и именно поэтому мы спросили ОП, что он знает или на чем он хочет основывать решение, вместо того, чтобы просто выбрать что-то самостоятельно, что, как мы не будем знать, сработает. - person Servy; 07.05.2012
comment
Чтобы предложить осмысленный алгоритм, действительно нужна дополнительная информация сверх того, что опубликовал OP. Как прокомментировал @Servy, вы ответили, не имея такой информации. - person Oded; 07.05.2012
comment
Вы знаете, что у вас есть файл с одинаковым количеством столбцов в каждой строке, кроме того, что вы ничего не знаете: он либо разделен вертикальной чертой, либо запятой, он может иметь текстовый квалификатор или нет, и вы знаете, что каждая строка имеет то же самое Число столбцов - person Badmiral; 07.05.2012
comment
Пожалуйста, обновите свой вопрос несколькими примерами: если в строке есть разделитель, будет ли во всех строках использоваться один и тот же разделитель? вы заранее знаете количество полей? Одно регулярное выражение может обрабатывать оба типа разделителей, а также удалять разделители кавычек, если они существуют. - person JotaBe; 08.05.2012
comment
@Серви. Мой ответ - это руководство того, как он может решить проблему. Конечно, это не точное решение, так как у меня нет всей необходимой информации. Когда я делаю такой ответ, следуя этому пути, если мне дают дополнительную информацию, я редактирую и улучшаю ее. Я также призываю ОП отредактировать свой вопрос, включив в него недостающую информацию, чтобы вопрос стал полезным для других людей без дополнительной информации в комментариях. - person JotaBe; 08.05.2012