in reply to Parsing a complex config file
The following parses the data into a structure somewhat like the one you describe. It doesn't insert extranious single element arrays and it is not robust against nested quoted strings, but it may be a useful starting point for your actual application.
use warnings; use strict; use Data::Dump::Streamer; my @libs; local $/ = 'libname='; # Read a record at a time while (<DATA>) { chomp; next if ! length; # Skip blank lines s/\n|\r/ /g; # Remove conventional line end characters next if ! s/(\S+)\s*//; my $str = $_; my %record; $record{libname} = $1; while ($str =~ /=/) { # Process an option last if ! ($str =~ s/\s*(\S+?)\s*=\s*//); my $opName = $1; my $opValue; if ($str =~ s/^\s*"([^"]*)"\s*//) { # Complicated option value $opValue = parseSubOps ($1); } elsif ($str =~ s/\s*(\S+)\s*//) { # Simple option $opValue = $1; } $record{$opName} = $opValue; } push @libs, {%record}; } Dump (\@libs); sub parseSubOps { my $str = shift; my %subOps; while ($str =~ /=/) { # Process a sub-option last if ! ($str =~ s/\s*(\S+)\s* = \s*\(\s* ([^)]*?) \)\s*//x) +; my $name = $1; my @values = $2 =~ /'([^']*?)'/g; $subOps{$name} = \@values; } return \%subOps; } __DATA__ libname=foo pathname=/path/to/metadata/foo owner=someuser libaclinheri +t=no dynlock=no roptions=" datapath=('/data/path1' '/data/path2' '/data/path3' ...) indexpath=('/indx/path1' '/indx/path2' '/indx/path3' ...) workpath=('/work/path1' '/work/path2' '/work/path3' ...) metapath=('/meta/path1' '/meta/path2' '/meta/path3' ...)"; libname=bar pathname=/path/to/metadata/bar owner=someuser libaclinheri +t=no dynlock=no roptions=" datapath=('/data/path1' '/data/path2' '/data/path3' ...) indexpath=('/indx/path1' '/indx/path2' '/indx/path3' ...) workpath=('/work/path1' '/work/path2' '/work/path3' ...) metapath=('/meta/path1' '/meta/path2' '/meta/path3' ...)"; libname=foobar pathname=/path/to/metadata;
Prints:
$ARRAY1 = [ { dynlock => 'no', libaclinherit => 'no', libname => 'foo', owner => 'someuser', pathname => '/path/to/metadata/foo', roptions => { datapath => [ '/data/path1', '/data/path2', '/data/path3' ], indexpath => [ '/indx/path1', '/indx/path2', '/indx/path3' ], metapath => [ '/meta/path1', '/meta/path2', '/meta/path3' ], workpath => [ '/work/path1', '/work/path2', '/work/path3' ] } }, { dynlock => 'no', libaclinherit => 'no', libname => 'bar', owner => 'someuser', pathname => '/path/to/metadata/bar', roptions => { datapath => [ '/data/path1', '/data/path2', '/data/path3' ], indexpath => [ '/indx/path1', '/indx/path2', '/indx/path3' ], metapath => [ '/meta/path1', '/meta/path2', '/meta/path3' ], workpath => [ '/work/path1', '/work/path2', '/work/path3' ] } }, { libname => 'foobar', pathname => '/path/to/metadata;' } ];
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Parsing a complex config file
by solitaryrpr (Acolyte) on Jul 12, 2006 at 14:08 UTC | |
by solitaryrpr (Acolyte) on Jul 12, 2006 at 17:33 UTC |