Анализ данных, разделенных запятыми

Проблема

Имеется файл данных, поля которого разделены запятыми. Однако в полях могут присутствовать свои запятые (находящиеся внутри строк или снабженные служебными префиксами). Многие электронные таблицы и программы для работы базами данных поддерживают списки полей, разделенных запятыми, в качестве стандартного формата для обмена данными.

Решение

Воспользуйтесь следующей процедурой:
sub parse_csv {
  my $text = shift;    # Запись со значениями, разделенными запятыми
  my @new = ():
  push(@new, $+) while $text =~ m {
                          # Первая часть группирует фразу в кавычках 
                          "([^\"\\]*(?:\\.[^\"\\]*)*)",?
                          | ([^,]+),?
                          | ,
                          }gx;
  push(@new, undef) if substr($text, -1,1) eq ',';
  return @new;  #Список значений, которые разделялись запятыми
}
Также можно воспользоваться стандартным модулем Text.ParseWords:
use Text::ParseWords;
sub parse_csv {
  return quoteword(",",0, $_[0]);
}

Комментарий

Ввод данных, разделенных запятыми, — коварная и непростая задача. Все выглядит просто, но в действительности приходится использовать довольно сложную систему служебных символов, поскольку сами поля могут содержать внутренние занятые. В результате подстановка получается весьма сложной, а простая функция split /, / вообще исключается.
К счастью, модуль Text::ParseWords скрывает от вас все сложности. Передайте функции qoutewords два аргумента и строку разделенных данных. Первый аргумент определяет символ-разделитель (в данном случае — запятая), а второй — логический флаг, который показывает, должна ли возвращаемая строка содержать внутренние кавычки.
Если кавычки должны присутствовать внутри поля, также ограниченного кавычками, воспользуйтесь префиксом \: "like \"this\". Кавычки, апострофы и обратная косая черта — единственные символы, для которых этот префикс имеет специальное значение. Все остальные экземпляры \ остаются в итоговой строке.
Ниже показан пример использования процедуры parse_csv. q<> — всего лишь хитроумный заменитель кавычек, благодаря которому нам не придется расставлять повсюду символы \.
$line = q<XYZZY, "", "0'Reilly, Inc", "Wall, Larry", "a\"glag\"bit," 5,
        "Error.   Core Dumped">;
@fields =  parse_csv($line);
for ($i = 0; $i < @fields; $i++) {
  print "$i : $fields[$i]\n";
}
0 : XYZZY
1 :
2 : O'Reilly, Inc
3 : Wall, Larry
4 : a \"glug\" bit,
5 : 5
6 : Error, Core Dumped

См. также




2013-09-10 17:05:19

Proverte kod v komentariyah gde pro list tam oshibki detskie




Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: