Регулярное выражение: сопоставление ',' после нуля или нечетного вхождения двойной кавычки - PullRequest
0 голосов
/ 18 января 2012

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

Полностью игнорируя последнее предложение, я решил изменить саму проблему следующим образом:

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

Пример:

text,"some,"chars,chars"more,""text",
    *     x      *          x       *

Где * - совпадения, а x - нет.возможность регулярного выражения, и если нет, то есть ли регулярное выражение, которое может обрабатывать этот тип ввода?

Ответы [ 2 ]

1 голос
/ 18 января 2012

Если ваш CSV-файл верен (каждое поле либо начинается и заканчивается «или не содержит»), вы можете проанализировать строку с помощью рекурсивной функции, например:

$csvString = 'zero,"o,ne",two,"thr,ee"';

function parseCsv($string, &$result)
{
    $regex = '/^((".*")|([^"].*))(,(.*))?$/U';
    $matches = array();
    preg_match($regex, $string, $matches);
    $result[] = $matches[1];
    if(isset($matches[5]))
    {
        parseCsv($matches[5], $result);
    }
}

$result = array();
parseCsv($csvString, $result);

var_dump($result);

Примечаниечто это не было проверено со строками в кавычках, которые содержат (экранированные) кавычки. Кроме того, он хранит кавычки вокруг строк в кавычках.

Результат вышеупомянутой функции:

array
  0 => string 'zero' (length=4)
  1 => string '"o,ne"' (length=6)
  2 => string 'two' (length=3)
  3 => string '"thr,ee"' (length=8)
1 голос
/ 18 января 2012

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

 preg_match_all('/
     \s* ((?: (?=.|(?<=,)$) [^",]* | "(?: ""|[^"]* )+" )+) \s* (?:,|$) /xms',
     $line, $matches
 )
 and print_r($matches[1]);

Но он не учитывает другие типичные правила CSV.Я обычно ожидал бы, что \" будет двойными кавычками внутри.И подстроки смешанные в кавычках и без кавычек также очень нестандартные.И в ней отсутствует какая-либо форма проверки, поэтому она просто пропустит любую последнюю цитату - что угодно, если не правильно спарена.

...