Регулярное выражение для разбора CSV в PHP - PullRequest
7 голосов
/ 22 января 2009

Мне уже удалось разделить файл CSV с помощью этого регулярного выражения: "/, (= (?:? [^ \"] \ "[^ \"] \ "?!) ([^ \"] \ ")) /"

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

Насколько я знаю, формат CSV может заключать строки в двойные кавычки, и все двойные кавычки, которые уже являются частью строки, удваиваются. Например:

Мой "другой" кот

становится

"Мой" "другой" "кот"

Что мне в основном нужно, так это регулярное выражение, которое заменит все последовательности из N двойных кавычек последовательностью (N / 2 - округленных в меньшую сторону) двойных кавычек.

Или есть лучший способ? Заранее спасибо.

Ответы [ 6 ]

21 голосов
/ 22 января 2009

Есть функция для чтения CSV-файлов: fgetcsv

4 голосов
/ 22 января 2009

Почему вы пытаетесь разделить файл с помощью регулярных выражений, когда есть функция fgetcsv, которая выполняет всю тяжелую работу за вас?

Вы можете передать разделитель и разделитель, и он определит, что делать.

2 голосов
/ 15 июня 2011
preg_split('/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/', $line,-1,PREG_SPLIT_DELIM_CAPTURE);

Имеет проблемы с "внутри строк, таких как" Игрушки "R" Нас "

Так что вы должны использовать вместо:

preg_split('/'.$seperator.'(?=(?:[^\"])*(?![^\"]))/', $line,-1, PREG_SPLIT_DELIM_CAPTURE);
2 голосов
/ 20 мая 2010

Для тех из вас, кто не хочет использовать регулярные выражения вместо fgetcsv. Вот полный пример того, как создать HTML-таблицу из CSV с помощью регулярных выражений.

    $data = file_get_contents('test.csv');
    $pieces = explode("\n", $data);

    $html .= "<table border='1'>\n";
    foreach (array_filter($pieces) as $line) {

            $html .= "<tr>\n";
            $keywords = preg_split('/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/', $line,-1,PREG_SPLIT_DELIM_CAPTURE);

            foreach ($keywords as $col) {
                    $html .= "<td>".trim($col, '"')."</td>\n";
            }
            $html .= "</tr>\n";
    }
    $html .= "</table>\n";
2 голосов
/ 23 января 2009

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

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

$csv_field = preg_replace('/"(.|$)/', '\1', $csv_field);

Это регулярное выражение соответствует кавычке, за которой следует любой символ или конец строки, и заменяет совпавший символ (ы) вторым символом или пустой строкой, если это было $, которое соответствовало. Согласно спецификации поля CSV могут содержать разделители строк; похоже, этого не происходит, но вы можете добавить модификатор 's' к регулярному выражению, если вам нужно.

0 голосов
/ 22 января 2009

Вот моя быстрая попытка, хотя она будет работать только на границах слов.

preg_replace('/([\W]){2}\b/', '\1', $csv)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...