Я пытался применить функцию Ruby CSV-to-array parse_csv
в соответствии с одним из популярного комментария автора, добавившего php. net запись для str_getcsv
.
(Смысл использования parse_csv
Рубли в том, что собственные функции синтаксического разбора PHP будут приводить к неожиданным результатам в различных сценариях ios, описанных здесь .)
Мой CSV-файл, accfinal.csv
, можно увидеть здесь (предупреждение о размере файла: 138 МБ) . Этот CSV-файл сложен, так как содержит неэкранированные двойные кавычки, HTML и даже JavaScript в полях, и это довольно большой, громоздкий CSV-файл.
В отдельном файле rubley_csv_parse.php
, у меня есть Функция Ruby CSV-to-array parse_csv
определяется следующим образом:
<?php
//https://www.php.net/manual/en/function.str-getcsv.php#113220
//parse a CSV file into a two-dimensional array
//this seems as simple as splitting a string by lines and commas, but this only works if tricks are performed
//to ensure that you do NOT split on lines and commas that are inside of double quotes.
function parse_csv($str)
{
//match all the non-quoted text and one series of quoted text (or the end of the string)
//each group of matches will be parsed with the callback, with $matches[1] containing all the non-quoted text,
//and $matches[3] containing everything inside the quotes
$str = preg_replace_callback('/([^"]*)("((""|[^"])*)"|$)/s', 'parse_csv_quotes', $str);
//remove the very last newline to prevent a 0-field array for the last line
$str = preg_replace('/\n$/', '', $str);
//split on LF and parse each line with a callback
return array_map('parse_csv_line', explode("\n", $str));
}
//replace all the csv-special characters inside double quotes with markers using an escape sequence
function parse_csv_quotes($matches)
{
//anything inside the quotes that might be used to split the string into lines and fields later,
//needs to be quoted. The only character we can guarantee as safe to use, because it will never appear in the unquoted text, is a CR
//So we're going to use CR as a marker to make escape sequences for CR, LF, Quotes, and Commas.
$str = str_replace("\r", "\rR", $matches[3]);
$str = str_replace("\n", "\rN", $str);
$str = str_replace('""', "\rQ", $str);
$str = str_replace(',', "\rC", $str);
//The unquoted text is where commas and newlines are allowed, and where the splits will happen
//We're going to remove all CRs from the unquoted text, by normalizing all line endings to just LF
//This ensures us that the only place CR is used, is as the escape sequences for quoted text
return preg_replace('/\r\n?/', "\n", $matches[1]) . $str;
}
//split on comma and parse each field with a callback
function parse_csv_line($line)
{
return array_map('parse_csv_field', explode(',', $line));
}
//restore any csv-special characters that are part of the data
function parse_csv_field($field) {
$field = str_replace("\rC", ',', $field);
$field = str_replace("\rQ", '"', $field);
$field = str_replace("\rN", "\n", $field);
$field = str_replace("\rR", "\r", $field);
return $field;
}
В моем случае я включаю файл определения rubley_csv_parse.php
и передаю accfinal.csv
в parse_csv
, но все, что я get - это пустой массив .
<?php
include('rubley_csv_parse.php');
$file = fopen("accfinal.csv","r");
//=======================NOT WORKING - As yet this just produces an empty array
//By using file_get_contents, you're not using any of PHP's native csv parsing functions first which breaks the CSV file
$str = file_get_contents("accfinal.csv");
$parsed_csv_array = parse_csv($str);
print_r($parsed_csv_array); //RESULTS IN AN EMPTY ARRAY
fclose($file);
В результате получается пустой массив , но я ожидал массив с содержимым:
[root@server files]# php -f accfinal_rubley_parse.php
Array
(
[0] => Array
(
[0] =>
)
)
Я считал, что parse_csv
Рубли был более надежным, чем любая из других функций синтаксического анализа csv, которые я видел. Я не уверен, был ли сбой в моем коде, или в функции Рубли возникла ситуация, с которой она не может справиться.
Где происходит сбой?