tags:

views:

116

answers:

5

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.

+2  A: 

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.

Dana
That's a bad regex for the split, since split's first argument is always interpreted as a regex.
Randal Schwartz
What's wrong about this regex?
Dana
looks OK to me...
Yair
Yair: The answer was edited since Randal's comment.
tsee
+5  A: 

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'
        ];
catwalk
+1  A: 
my @a = split /\]\s*,\s*\[/, $data;

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

el.pescado
A: 

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

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

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

ghostdog74