Haiyuan Zhang
Haiyuan Zhang

Reputation: 42852

How can I parse CSV data with internal commas in data using Perl?

The data I need to parse looks like:

[fild1, filed2, .... filedn] , [filed1, filed2, .... filedn] .....

I call it a special form of CSV data because there are two kinds of comma:

  1. those commas outside the [] pair are served as the separator between different records.
  2. those commas inside the [] pair are served as the separator between different fields.

So in this case using split(',' , $data) will not serve my needs which is to parse the data and get every record in the data.

Upvotes: 1

Views: 410

Answers (5)

ghostdog74
ghostdog74

Reputation: 343211

you can also try out Text::CSV or Text::CSV_XS. go to CPAN to download.

Upvotes: 0

Brad Gilbert
Brad Gilbert

Reputation: 34140

Here is a quick example that assumes that the value in $data is valid.

my @data = map { [ split ',', $_ ] } $data =~ / \[ ([^\[\]]*) \] ,? /xg;

Upvotes: 0

Dana
Dana

Reputation: 2759

How about: my @parts = split(/\]/, $data);, and then you can iterate over @parts, remove the heading [ and split once more by ","

You can also make the initial split like so: my @parts = split(/\] , /, $data); and that will save you some more cleanup later. Just be sure to only use this method if your data's whitespaces are consistent.

Upvotes: 2

my @a = split /\]\s*,\s*\[/, $data;

and get rid of first '[' and last ']'.

Upvotes: 1

catwalk
catwalk

Reputation: 6476

This should do the job:

my @out = map{[split/,/]} $data =~ /\[([^\]]+)\]/g;

example:

use Data::Dumper;
$data='[1,2,3],[4,5],[6]';
@a=map{[split/,/]} $data =~ /\[([^\]]+)\]/g;
print Dumper @a;

output:

$VAR1 = [
          '1',
          '2',
          '3'
        ];
$VAR2 = [
          '4',
          '5'
        ];
$VAR3 = [
          '6'
        ];

Upvotes: 5

Related Questions