2013-05-30 3 views
1

Я создаю инструмент, который будет принимать CSV или файл с разделителями табуляции, который затем будет анализироваться и база данных будет удалена.Обнаружение формата файла в PHP

Загруженный файл может быть CSV или с разделителем табуляции.

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

Благодаря

<?php 

$csv_comma='Fruit,Color 
Apple,"Red,Green" 
Tomato,"Red,Green" 
Banana,Yellow 
Tangerine,Orange 
'; 


$csv_semi_colon='Fruit;Color 
Apple;"Red,Green" 
Tomato;"Red,Green" 
Banana;Yellow 
Tangerine;Orange 
'; 


$tab_delimited='Fruit Color 
Apple Red,Green 
Tomato Red,Green 
Banana Yellow 
Tangerine Orange'; 


$fileArr = array($csv_comma,$csv_semi_colon,$tab_delimited); 


foreach($fileArr as $file){ 

    if(preg_match('/^(.+),(.+)/',trim($file))){ 

     echo "CSV with comma separator"; 

    } 

    if(preg_match('/^(.+);(.+)/',trim($file))){ 

     echo "CSV with semi colon separator"; 

    } 


    if(preg_match('/^(.+)\t(.+)/',trim($file))){ 

     echo "Tab delimited"; 

    } 
} 
+0

Любая эвристика даст неправильные результаты. Вы просто не можете угадать 100% прав, какой разделитель использовался – zerkms

+2

[Здесь] (http://stackoverflow.com/a/762307/20670), как это делает Python. –

+0

Почему бы просто не попробовать разбор csv с помощью 'fgetcsv' с', или; ... и т. д. как ваш делиметр? Если он терпит неудачу, он не должен быть действительным csv. – brbcoding

ответ

1

Ну CSV имеет этот Prety много реализован. По умолчанию для csv находится ,, но с sep= вы можете указать другой разделитель.

Вы можете просто реализовать это как csv. Таким образом, у вас есть значение по умолчанию ,, но если определено значение sep, вы его используете.

Вы файл может выглядеть следующим образом:

apple, orange, tomato 

или

sep=; 
apple; orange; tomato 

Таким образом, если первая строка начинается с сентября, это строка «вариант» в противном случае есть значения. Для вкладки вы делаете sep=\t

Теперь пользователи могут определять там собственный Seperator и не нужно гадать, не больше,


После некоторых замечаний CBroe простых в использовании для пользователя там могут быть некоторые изменения. csv принимает только один charachter как septerator, так что система может использоваться как выше. Редактор cvs (например, excel) будет обрабатывать это для пользователя

Если пользователь использует вкладку, это не будет файл csv, а .txt (например). Таким образом, вы можете изменить значение по умолчанию в соответствии с указанным файлом.

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

Я не знаю, как настроить файлы, но строки csv должны быть одинаковой длины (в соответствии с моей памятью). Итак, что вы можете сделать, это зачитать первые строки x. и использовать каждый разделитель.

После этого проверьте, какие длины линий одинаковы, наиболее вероятно, что ваш Seperator (опять угадал)

+0

Это потребует изменения файла CSV - возможно, это не удобно или даже возможно. – CBroe

+0

Откройте файл csv с помощью текстового редактора. Вы также можете сделать .txt-файл с этой настройкой. – MKroeders

+0

_ «Открыть файл csv с помощью текстового редактора». - Вау, почему я не подумал об этом? '' - серьезно, по соображениям удобства (_ «Что, я должен изменить свой файл перед загрузкой?» _), Который может и не быть вариантом, а также не очень технологичные пользователи могут испортить файл при попытке делайте то, что им задают ... поэтому я не говорю, что ваш ответ - это _wrong_ или не возможное решение, - но просто это может создать большую проблему, чем это фактически решает. – CBroe

0

Вы можете использовать этот вид шаблона для проверки структуры CSV и определить разделитель:

if (preg_match('^(?:("[^"]++"|[^,;\t\n]++)(?<sep>[,\t;])(?1)(?:\n|$))++$', $csv_comma, $match)) 
    print_r($match['sep']); 
Смежные вопросы