Автоопределение наличия заголовков CSV в файле

Короткий вопрос: как автоматически определить, есть ли в CSV-файле заголовки в первой строке?

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

Я пытаюсь найти надежный способ автоматического обнаружения присутствия CSV-заголовков, поэтому скрипт может решить, использовать ли первую строку CSV-файла в виде имен ключей / столбцов или сразу же начать анализировать данные. Поскольку все, что мне нужно, это логический тест, я мог бы легко указать аргумент после проверки файла CSV сам, но мне бы не пришлось (идти на автоматизацию).

Полагаю, мне придется разбирать первые 3? строки CSV-файла и искать какой-то шаблон для сравнения с заголовками. У меня есть кошмары из трех особенно плохих случаев, в которых:

  1. Заголовки содержат числовые данные по какой-либо причине
  2. Первые несколько строк (или больших частей CSV) равны нулю
  3. Там заголовки и данные выглядят слишком похожими, чтобы рассказать им обособленно

Если я могу получить «лучшее предположение» и сбой анализатора с ошибкой или выплюнуть предупреждение, если он не может решить, все в порядке. Если это то, что будет чрезвычайно дорогостоящим с точки зрения времени или вычисления (и потребуется больше времени, чем это должно было спасти меня), я с радостью откажусь от идеи и вернусь к работе над «важными вещами».

Я работаю с PHP, но это ставит меня скорее как алгоритмический / вычислительный вопрос, чем что-то специфичное для реализации. Если есть простой алгоритм, который я могу использовать, отлично. Если вы можете указать мне на какую-то соответствующую теорию / дискуссию, это тоже здорово. Если есть гигантская библиотека, которая обрабатывает естественный язык или 300 различных видов разбора, меня это не интересует.

Solutions Collecting From Web of "Автоопределение наличия заголовков CSV в файле"

Как указывали другие, вы не можете сделать это со 100% -ной надежностью. Бывают случаи, когда получение «в основном правильное» полезно, однако, например, инструменты таблиц с функциями импорта CSV часто пытаются понять это самостоятельно. Вот несколько эвристик, которые, как правило, указывают, что первая строка не является заголовком:

  • Первая строка содержит столбцы, которые не являются ни строками, ни пустыми
  • Столбцы первой строки не все уникальны
  • Первая строка содержит даты или другие общие форматы данных (например, xx-xx-xx)

В самом общем смысле это невозможно. Это действительный файл csv:
имя
Джим
Том
Билл

Большинство читателей csv просто возьмут hasHeader в качестве опции и позволят вам передать свой собственный заголовок, если хотите. Даже в том случае, если вы считаете, что можете обнаружить, что являетесь символьными заголовками и числовыми данными, вы можете столкнуться с катастрофическим сбоем. Что, если ваша колонка – это список серий BMW?
M
3
5
7

Вы обработаете это неправильно. Хуже всего, вы потеряете лучший автомобиль!

В чисто абстрактном смысле я не думаю, что на ваш вопрос существует безошибочный алгоритмический ответ, поскольку он сводится к следующему: «Как отличить dataA от dataB, если я ничего не знаю об этом?». Всегда будет потенциал для того, чтобы dataA был неотличим от dataB. Тем не менее, я бы начал с простой и единственной сложности при необходимости. Например, если рассматривать первые пять строк для данного столбца (или столбцов), если тип данных в строках 2-5 все одинаковы, но отличается от типа данных в строке 1, есть хорошая вероятность, что строка заголовка присутствует ( увеличенные размеры выборок уменьшают вероятность ошибки). Это могло бы (sorta) решить # 1 / # 3 – возможно, выбросить исключение, если все строки заполнены, но данные неотличимы, чтобы позволить вызывающей программе решить, что делать дальше. Для # 2 просто не считайте строку как строку, пока и пока она не вытащит ненулевые данные …, которые будут работать во всех, кроме пустого файла (в этом случае вы попали бы в EOF). Это никогда не будет безупречным, но это может быть «достаточно близко».

Это действительно зависит от того, как «общий» вы хотите, чтобы ваш инструмент был. Если данные всегда будут числовыми, вам будет легко, если вы принимаете нечисловые заголовки (что кажется довольно справедливым допущением).

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

FWIW, я на самом деле просто написал сценарий для разбора некоторых вещей из TSV, все из одного источника. Подход источника к заголовкам / форматированию был настолько разбросан, что имеет смысл просто заставить скрипт задавать мне вопросы из командной строки во время выполнения. (Это заголовок? Какие столбцы важны?). Так что нет автоматизации, но это позволяет мне летать через набор данных, над которыми я работаю, вместо того, чтобы предвидеть каждый забавный случай форматирования. Кроме того, мои ответы сохраняются в файле, поэтому я должен участвовать только один раз в файле. Не идеальный, но эффективный.

Если у вас CSV такой заголовок.

ID, имя, адрес электронной почты, дата 1, john, john@john.com, 12 jan 2020

Затем выполнение фильтра_var (str, FILTER_VALIDATE_EMAIL) в строке заголовка завершится ошибкой. Поскольку адрес электронной почты находится только в данных строки. Поэтому проверьте строку заголовка для адреса электронной почты (если в вашем CSV есть адреса электронной почты).

Вторая идея. http://php.net/manual/en/function.is-numeric.php Проверьте строку заголовка для is_numeric, скорее всего, строка заголовка не содержит числовых данных. Но, скорее всего, строка данных будет иметь числовые данные.

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

Очевидно, вам нужно, какой тип данных вы ожидаете. Я «ожидаю» адреса электронной почты.