cómo saber si los campos del archivo csv están delimitados por tabulaciones o delimitados por comas. Necesito la validación de php para esto. ¿Alguien puede ayudar? Gracias por adelantado.cómo saber si los campos del archivo csv están delimitados por tabulaciones o delimitados por comas
cómo saber si los campos del archivo csv están delimitados por tabulaciones o delimitados por comas
Respuesta
No hay una manera 100% confiable de determinar esto. Lo que puede hacer es
- Si tiene un método para validar los campos que lee, intente leer algunos campos usando el separador y valide contra su método. Si se rompe, usa otro.
- Cuente la aparición de pestañas o comas en el archivo. Por lo general, uno es significativamente más alto que el otro
- Por último, pero no por ello menos importante: pregúntele al usuario y permítale que anule sus suposiciones.
Aparte de la respuesta trivial de que c archivos sv están siempre separados por comas - está en el nombre, no creo que se puede llegar a ninguna regla dura. Los archivos TSV y CSV están lo suficientemente especificados como para que pueda encontrar archivos que serían aceptables.
A\tB,C
1,2\t3
(Suponiendo \ t == TAB)
¿Cómo se decide si se trata de TSV o CSV?
La c puede representar 'carácter', lo que hace,; o \ t todas las opciones válidas. – julesj
@julesj Una búsqueda rápida sugiere muy pocas usando el carácter c para referirse a la mayoría de los significados. Aunque incluso entonces, el separador no es siempre una coma, solo para complicar las cosas. –
Cuando salida de un archivo TSV Me autor las pestañas usando \ t el mismo método que uno autor de un salto de línea como \ n para que se decía que supongo un método podría ser el siguiente:
<?php
$mysource = YOUR SOURCE HERE, file_get_contents() OR HOWEVER YOU WISH TO GET THE SOURCE;
if(strpos($mysource, "\t") > 0){
//We have a tab separator
}else{
// it might be CSV
}
?>
I Adivina que esta puede no ser la manera correcta, porque también podrías tener pestañas y comas en el contenido real. Es solo una idea Usar expresiones regulares puede ser mejor, aunque no estoy muy al tanto de eso.
La forma más fácil de responder esto es abrirlo en un editor de texto plano, o en TextMate.
Esto no se aplica en absoluto a la pregunta formulada. – Jacta
En mi situación, los usuarios proporcionan archivos csv que luego se ingresan en una base de datos SQL. Pueden guardar una hoja de cálculo de Excel como archivos delimitados por comas o tabuladores. Un programa que convierte la hoja de cálculo a SQL necesita identificar automáticamente si los campos están separados por tabulaciones o por comas
Muchas exportaciones de Excel csv tienen encabezados de campo como primera línea. Es poco probable que la prueba de encabezado contenga comas, excepto como delimitador. Para mi situación conté las comas y las pestañas de la primera línea y la uso con el número mayor para determinar si es csv o pestaña
Esto es lo que hago.
- analizar los primeros 5 líneas de un archivo CSV
- contar el número de delimitadores [comas, pestañas, punto y coma y dos puntos] en cada línea
- comparar el número de delimitadores en cada línea. Si tiene un CSV formateado correctamente, uno de los conteos de delimitador coincidirá en cada fila.
Esto no funcionará el 100% del tiempo, pero es un punto de partida decente. Como mínimo, reducirá el número de delimitadores posibles (lo que facilita a los usuarios seleccionar el delimitador correcto).
/* Rearrange this array to change the search priority of delimiters */
$delimiters = array('tab' => "\t",
'comma' => ",",
'semicolon' => ";"
);
$handle = file($file); # Grabs the CSV file, loads into array
$line = array(); # Stores the count of delimiters in each row
$valid_delimiter = array(); # Stores Valid Delimiters
# Count the number of Delimiters in Each Row
for ($i = 1; $i < 6; $i++){
foreach ($delimiters as $key => $value){
$line[$key][$i] = count(explode($value, $handle[$i])) - 1;
}
}
# Compare the Count of Delimiters in Each line
foreach ($line as $delimiter => $count){
# Check that the first two values are not 0
if ($count[1] > 0 and $count[2] > 0){
$match = true;
$prev_value = '';
foreach ($count as $value){
if ($prev_value != '')
$match = ($prev_value == $value and $match == true) ? true : false;
$prev_value = $value;
}
} else {
$match = false;
}
if ($match == true) $valid_delimiter[] = $delimiter;
}//foreach
# Set Default delimiter to comma
$delimiter = ($valid_delimiter[0] != '') ? $valid_delimiter[0] : "comma";
/* !!!! This is good enough for my needs since I have the priority set to "tab"
!!!! but you will want to have to user select from the delimiters in $valid_delimiter
!!!! if multiple dilimiter counts match
*/
# The Delimiter for the CSV
echo $delimiters[$delimiter];
Funciona bien. Lo usé como una función antes de analizar mis archivos. El valor de retorno de la misma, ** $ delimitadores [$ delimitador] ** Lo usé en ** str_getcsv ($ value, $ delimeter); ** – MJoraid
También puede utilizar fgetcsv (http://php.net/manual/en/function.fgetcsv.php) pasándole un parámetro delimitador. Si la función devuelve falso, significa que el parámetro $ delimitador no era el correcto
muestra para comprobar si el delimitador es ';'
if (($data = fgetcsv($your_csv_handler, 1000, ';')) !== false) { $csv_delimiter = ';'; }
$ csv_delimiter = ';'; en lugar de $ csv_delimiter = ';' –
mi mal! acaba de editarlo – Rommy
Lamentablemente esto no funcionó para mí – antongorodezkiy
Sólo estoy contando las apariciones de los diferentes delimitadores en el archivo CSV, el que tiene la mayor parte probablemente debería ser el delimitador correcto:
//The delimiters array to look through
$delimiters = array(
'semicolon' => ";",
'tab' => "\t",
'comma' => ",",
);
//Load the csv file into a string
$csv = file_get_contents($file);
foreach ($delimiters as $key => $delim) {
$res[$key] = substr_count($csv, $delim);
}
//reverse sort the values, so the [0] element has the most occured delimiter
arsort($res);
reset($res);
$first_key = key($res);
return $delimiters[$first_key];
Es demasiado tarde para responder a esta pregunta, pero Espero que ayude a alguien.
Aquí hay una función simple que devolverá un delimitador de un archivo.
function getFileDelimiter($file, $checkLines = 2){
$file = new SplFileObject($file);
$delimiters = array(
',',
'\t',
';',
'|',
':'
);
$results = array();
$i = 0;
while($file->valid() && $i <= $checkLines){
$line = $file->fgets();
foreach ($delimiters as $delimiter){
$regExp = '/['.$delimiter.']/';
$fields = preg_split($regExp, $line);
if(count($fields) > 1){
if(!empty($results[$delimiter])){
$results[$delimiter]++;
} else {
$results[$delimiter] = 1;
}
}
}
$i++;
}
$results = array_keys($results, max($results));
return $results[0];
}
Utilice esta función como se muestra a continuación: preg_split
$delimiter = getFileDelimiter('abc.csv'); //Check 2 lines to determine the delimiter
$delimiter = getFileDelimiter('abc.csv', 5); //Check 5 lines to determine the delimiter
PS He utilizado() en lugar de explotar() debido a explotar ('\ t', $ valor) no dará adecuada resultados.
ACTUALIZACIÓN: Gracias por @RichardEB señalando un error en el código. He actualizado esto ahora.
$ line = .... debe reemplazarse por: if (! $ Line = $ file-> fgets()) {break;} If $ CheckLines excede el recuento de líneas del archivo csv y habrá un error. –
No hay problema, excepto que su corrección todavía arroja una excepción 'No se puede leer del archivo' cuando $ checkLines excede la cantidad de líneas de csv. Si desea compilar el cheque en el ciclo while, debe ser: while ($ file-> valid() && $ i <$ checkLines) –
'Works for me' no es un buen argumento contra la lógica booleana incorrecta (p. Ej. , su configuración de manejo de errores puede ser diferente). La expresión while utiliza O no Y, y por lo tanto, se ignorará el 'final del archivo' cuando $ i esté por debajo de $ checkLines. Por ejemplo, en el archivo CSV de 1 fila, $ i se le permitirá contar hasta tres filas independientemente de que se haya alcanzado el EOF, simplemente porque (2 <= 2) = TRUE –
Esta es mi solución. Funciona si sabe cuántas columnas espera. Por último, el carácter separador es el $ actual_separation_character
$separator_1=",";
$separator_2=";";
$separator_3="\t";
$separator_4=":";
$separator_5="|";
$separator_1_number=0;
$separator_2_number=0;
$separator_3_number=0;
$separator_4_number=0;
$separator_5_number=0;
/* YOU NEED TO CHANGE THIS VARIABLE */
// Expected number of separation character (3 colums ==> 2 sepearation caharacter/row)
$expected_separation_character_number=2;
$file = fopen("upload/filename.csv","r");
while(! feof($file)) //read file rows
{
$row= fgets($file);
$row_1_replace=str_replace($separator_1,"",$row);
$row_1_length=strlen($row)-strlen($row_1_replace);
if(($row_1_length==$expected_separation_character_number)or($expected_separation_character_number==0)){
$separator_1_number=$separator_1_number+$row_1_length;
}
$row_2_replace=str_replace($separator_2,"",$row);
$row_2_length=strlen($row)-strlen($row_2_replace);
if(($row_2_length==$expected_separation_character_number)or($expected_separation_character_number==0)){
$separator_2_number=$separator_2_number+$row_2_length;
}
$row_3_replace=str_replace($separator_3,"",$row);
$row_3_length=strlen($row)-strlen($row_3_replace);
if(($row_3_length==$expected_separation_character_number)or($expected_separation_character_number==0)){
$separator_3_number=$separator_3_number+$row_3_length;
}
$row_4_replace=str_replace($separator_4,"",$row);
$row_4_length=strlen($row)-strlen($row_4_replace);
if(($row_4_length==$expected_separation_character_number)or($expected_separation_character_number==0)){
$separator_4_number=$separator_4_number+$row_4_length;
}
$row_5_replace=str_replace($separator_5,"",$row);
$row_5_length=strlen($row)-strlen($row_5_replace);
if(($row_5_length==$expected_separation_character_number)or($expected_separation_character_number==0)){
$separator_5_number=$separator_5_number+$row_5_length;
}
} // while(! feof($file)) END
fclose($file);
/* THE FILE ACTUAL SEPARATOR (delimiter) CHARACTER */
/* $actual_separation_character */
if ($separator_1_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_1;}
else if ($separator_2_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_2;}
else if ($separator_3_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_3;}
else if ($separator_4_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_4;}
else if ($separator_5_number==max($separator_1_number,$separator_2_number,$separator_3_number,$separator_4_number,$separator_5_number)){$actual_separation_character=$separator_5;}
else {$actual_separation_character=";";}
/*
if the number of columns more than what you expect, do something ...
*/
if ($expected_separation_character_number>0){
if ($separator_1_number==0 and $separator_2_number==0 and $separator_3_number==0 and $separator_4_number==0 and $separator_5_number==0){/* do something ! more columns than expected ! */}
}
Gracias por todas sus entradas, hice mío el uso de sus trucos: preg_split, fgetcsv, bucle, etc.
Pero he implementado algo que sorprendentemente no era ¡Aquí, el uso de fgets en lugar de leer todo el archivo, mucho mejor si el archivo es pesado!
Aquí está el código:
ini_set("auto_detect_line_endings", true);
function guessCsvDelimiter($filePath, $limitLines = 5) {
if (!is_readable($filePath) || !is_file($filePath)) {
return false;
}
$delimiters = array(
'tab' => "\t",
'comma' => ",",
'semicolon' => ";"
);
$fp = fopen($filePath, 'r', false);
$lineResults = array(
'tab' => array(),
'comma' => array(),
'semicolon' => array()
);
$lineIndex = 0;
while (!feof($fp)) {
$line = fgets($fp);
foreach ($delimiters as $key=>$delimiter) {
$lineResults[$key][$lineIndex] = count (fgetcsv($fp, 1024, $delimiter)) - 1;
}
$lineIndex++;
if ($lineIndex > $limitLines) break;
}
fclose($fp);
// Calculating average
foreach ($lineResults as $key=>$entry) {
$lineResults[$key] = array_sum($entry)/count($entry);
}
arsort($lineResults);
reset($lineResults);
return ($lineResults[0] !== $lineResults[1]) ? $delimiters[key($lineResults)] : $delimiters['comma'];
}
¿Qué tal algo simple?
function findDelimiter($filePath, $limitLines = 5){
$file = new SplFileObject($filePath);
$delims = $file->getCsvControl();
return $delims[0];
}
Esto no funciona porque getCsvControl() solo devuelve lo que se ha establecido manualmente utilizando la función setCsvControl(). No hace ninguna conjetura mágica. – ethan
Si tiene un ejemplo de archivo muy grande en GB, encabece las primeras líneas, coloque un archivo temporal. Abrir el archivo temporal en vi
head test.txt > te1
vi te1
¡Esto no es lo que pidió OP! – CinCout
Solía solución de @Jay Bhatt para averiguar delimitador de un archivo csv, pero no funcionó para mí, así que he aplicado algunas correcciones y comentarios para que el proceso sea más comprensible.
Ver mi versión de la función de @Jay Bhatt:
function decide_csv_delimiter($file, $checkLines = 10) {
// use php's built in file parser class for validating the csv or txt file
$file = new SplFileObject($file);
// array of predefined delimiters. Add any more delimiters if you wish
$delimiters = array(',', '\t', ';', '|', ':');
// store all the occurences of each delimiter in an associative array
$number_of_delimiter_occurences = array();
$results = array();
$i = 0; // using 'i' for counting the number of actual row parsed
while ($file->valid() && $i <= $checkLines) {
$line = $file->fgets();
foreach ($delimiters as $idx => $delimiter){
$regExp = '/['.$delimiter.']/';
$fields = preg_split($regExp, $line);
// construct the array with all the keys as the delimiters
// and the values as the number of delimiter occurences
$number_of_delimiter_occurences[$delimiter] = count($fields);
}
$i++;
}
// get key of the largest value from the array (comapring only the array values)
// in our case, the array keys are the delimiters
$results = array_keys($number_of_delimiter_occurences, max($number_of_delimiter_occurences));
// in case the delimiter happens to be a 'tab' character ('\t'), return it in double quotes
// otherwise when using as delimiter it will give an error,
// because it is not recognised as a special character for 'tab' key,
// it shows up like a simple string composed of '\' and 't' characters, which is not accepted when parsing csv files
return $results[0] == '\t' ? "\t" : $results[0];
}
yo personalmente utilizar esta función para ayudar a analizar un archivo de forma automática con PHPExcel, y funciona muy bien y rápido.
Recomiendo analizar al menos 10 líneas, para que los resultados sean más precisos.Personalmente lo uso con 100 líneas, y está funcionando rápido, sin demoras ni retrasos. Cuantas más líneas analizas, más preciso es el resultado.
NOTA: Esta es solo una versión modificada de la solución de @Jay Bhatt a la pregunta. Todos los créditos van a @Jay Bhatt.
- 1. Excel y archivos delimitados por tabulaciones Pregunta
- 2. Regex: enteros delimitados por comas
- 3. XML vs archivos de texto delimitados por comas
- 4. C# Leer archivo de texto que contiene datos delimitados por tabulaciones
- 5. Lectura de archivo de texto delimitado por comas o tabulaciones
- 6. Ciudad de los EE. UU., Estado y código postal en XML, JSON o comas delimitados?
- 7. ¿Cuál es la extensión de archivo aceptada para usar para archivos delimitados por tuberías?
- 8. Dividir una columna de datos concatenados delimitados por comas y recodificar la salida como factores
- 9. Lectura de archivos delimitados en C++
- 10. palabras separadas delimitados por espacios en una cadena
- 11. ¿Cómo convertir un archivo separado por tabulaciones al formato CSV?
- 12. Entidades en contextos delimitados en Diseño controlado por dominio
- 13. Ordenando números delimitados por espacios con Linux/Bash
- 14. C# - ¿Cómo analizar el archivo de texto (espacios delimitados por números)?
- 15. Bash: ordenar el archivo csv por las primeras 4 columnas
- 16. Necesita ayuda para dividir esta cadena de nombres (nombre y apellido pares delimitados por comas y "y")
- 17. Cómo importar datos de archivos de texto delimitados por tuberías a la tabla de SQL Server
- 18. Cómo convertir un archivo separado por tabulaciones en coma archivo separado por
- 19. Archivos CSV con caracteres de comas y comas dentro de los campos
- 20. Python palabras delimitados por espacios separados de expresiones regulares en una lista
- 21. leer el archivo CSV con comas dentro de los campos en Python
- 22. ¿Cómo puedo generar un archivo CSV (archivo de texto delimitado por comas) para descargar con ASP.NET?
- 23. Insertar números delimitados específicos en una columna en SQL Server
- 24. forma más rápida de convertir archivo delimitado por tabulaciones a csv en linux
- 25. ¿Cómo analizo los campos en una cadena separada por comas usando sscanf mientras apoyo campos vacíos?
- 26. cheque MySQL si los números están en una lista separada por comas
- 27. Comas dentro de los datos CSV
- 28. ¿Cómo saber si los rieles están en producción?
- 29. Iphone Cómo saber si los auriculares Bluetooth están conectados
- 30. csv de análisis por comas, comillas dobles y codificación
Mire la extensión del curso :) La tabulación delimitada debe ser '.tsv' –