Как я могу проверить этот файл CSV перед началом синтаксического анализа с помощью fgetcsv
?
Ответ 1
Я бы не стал проверять файл перед рукой: я предпочел бы переходить через него по строкам, имея дело с каждой строкой отдельно:
- Чтение одной строки
- Подтверждение OK
- используя данные
- и переход к следующей строке.
Теперь, что может "подтвердить это ОК" означает?
- По крайней мере: убедитесь, что я могу прочитать строку как CSV, с моим обычным набором функций (возможно,
fgetcsv
, может быть, какой-то другой функцией, специфичной для моего проекта), в любом случае, если я не могу прочитать одну строку с моей функцией, читает сотни, возможно, потому, что в этой строке есть проблема)
- Затем проверьте количество полей
- то для каждого поля проверьте, содержит ли он "действительные" данные
- обязательный? optionnal?
- числовые?
- строка?
- дата?
- и т.д.
- то для каждого поля некоторые более тщательные проверки
- например, для поля "code": соответствует ли это значение, допустимое для моего приложения?
Если все идет хорошо - ну, не намного больше делать, кроме использования данных;-)
И когда вы закончите с одной строкой, просто переходите к следующему.
Конечно, если вы хотите либо принять, либо отклонить весь файл, прежде чем делать какую-либо базу данных (или что-то еще подобное), вам придется:
- проанализируйте файл по строкам, применяя "проверяющие" идеи
- хранить данные каждой строки в памяти
- и, когда весь файл был прочитан в память,
- либо начать использовать данные
- или, если в одной строке была ошибка, отклоните все.
В вашем конкретном случае у вас есть три вида полей:
Date;Id;Shown
15-Mar-10;231;345
15-Mar-10;232;346
Из чего я могу догадаться:
- Первым должен быть дата
- Использование некоторого регулярного выражения для проверки того, что будет непросто: не существует одинакового количества дней в месяц, есть много месяцев, в феврале нет такого же количества дней в зависимости от года,...
- В таком случае я, вероятно, попытаюсь проанализировать дату с помощью
strtotime
(не уверен, что это нормально для формата, который вы 're использование, хотя)
- Или я просто
explode
строка
- убедитесь, что есть три части.
- что третий - 2 цифры
- что вторая одна из
Jan
, Feb
, Mar
,...
- То, что первое соответствует правильному количеству дней, в зависимости от двух других.
- Второй:
- должно быть целым числом
- должно быть допустимым значением, которое существует в вашей базе данных?
- Если это так, простой SQL-запрос позволит вам проверить, что
- Для третьего, не совсем уверен...
- Я предполагаю, что это должно быть целое число?
Ответ 4
Я написал инструмент Python с открытым исходным кодом для упрощения проверки таких файлов, доступных из http://pypi.python.org/pypi/cutplace/.
Основная идея заключается в том, что вы описываете формат данных в структурированной спецификации интерфейса, используя OpenOffice.org, Excel или простой CSV. Это делается через несколько минут и достаточно читаемо, чтобы служить в документации. Мы используем его для проверки файлов с примерно 200 000 строк на ежедневной основе.
Вы можете проверить файл CSV с помощью командной строки:
cutplace specification.csv data.csv
В случае обнаружения недействительных строк данных код выхода равен 1. Если вам нужно больше элемента управления, вы можете написать небольшой Python script, который импортирует модуль cutplace и добавляет прослушиватель для событий проверки.
В качестве примера, здесь приведена спецификация, которая проверила бы данные образца, которые вы предоставили, заполнив пробелы в вашем кратком описании, сделав несколько предположений. (Я пишу спецификацию в CSV, чтобы включить ее в этот пост. На практике я предпочитаю OpenOffice.org Calc и ODS, потому что я могу использовать больше форматов и упрощать чтение и обслуживание.)
,"Interface: Show statistics"
,
,"Data format"
"D","Format","CSV"
"D","Item delimiter",";"
"D","Header","1"
"D","Encoding","ASCII"
,
,"Fields"
,"Name","Example","Empty","Length","Type","Rule"
"F","date","15-Mar-10",,,"RegEx","\d\d-[A-Z][a-z][a-z]-\d\d"
"F","id","231",,,"Integer","0:"
"F","shown","345",,,"Integer","0:"
,
,"Checks"
,"Description","Type","Rule"
"C","id per date must be unique","IsUnique","date, id"
Строки, начинающиеся с "D", описывают базовый формат данных. В этом случае это CSV файл с использованием ";" как разделитель с 1 строкой заголовка в кодировке ASCII.
Строки, начинающиеся с "F", описывают различные поля. Например,
,"Name","Example","Empty","Length","Type","Rule"
"F","id","231",,,"Integer","0:"
определяет обязательное поле "id" типа Integer со значением 0 или больше. Чтобы разрешить пустое поле, укажите "X" в столбце "Пусто":
,"Name","Example","Empty","Length","Type","Rule"
"F","id","231","X",,"Integer","0:"
Наконец, есть необязательный раздел, чтобы содержать больше проверок, которые порождают весь файл, а не только отдельные строки. Например, если каждая дата в вашем файле должна указывать дату для идентификатора только один раз, вы можете указать это, используя:
,"Description","Type","Rule"
"C","id per date must be unique","IsUnique","date, id"
Любая строка, начинающаяся с пустого столбца, может содержать любой текст, который вам нравится, и не будет обрабатываться во время проверки. Это полезно для заголовков, комментариев и т.д.