in reply to Help with regex for complicated key=value string
use strict; use warnings; sub dequote { my ($s) = @_; if ($s =~ /^"/) { $s =~ s/^"//; $s =~ s/"$//; } else { $s =~ s/\\([\\,])/$1/g; } return $s; } sub parse { my @terms; for ($_[0]) { my $key = /\G ( [^=,]+ ) = /xgc ? $1 : undef; my $val = /\G ( " [^"]+ " | (?: [^\\,] | \\[\\,] )* ) /xgc && dequote("$1"); push @terms, [ $key, $val ]; /\G $ /xgc and last; /\G , /xgc or die("Expected comma at pos ", pos(), "\n"); redo; } return @terms; } # --- use Data::Dumper qw( Dumper ); my $str = join ',', <<'__EOI__' =~ /.+/g; key=value\,value key=\\ key="value,value" value __EOI__ my @terms = parse($str); local $Data::Dumper::Indent = 1; local $Data::Dumper::Terse = 1; local $Data::Dumper::Useqq = 1; print(Dumper(\@terms), "\n");
The above assumes slashes can also be escaped.
The above otherwise assumes everything you didn't specify is disallowed.
The following might be better to get the value, but differs from what you asked:
sub dequote { my ($s) = @_; if ($s =~ /^"/) { $s =~ s/^"//; $s =~ s/"$//; } $s =~ s/\\(.)/$1/sg; return $s; } my $val = /\G ( " (?: [^\\"] | \\. )* " | (?: [^\\,] | \\. )* ) /xsgc && dequote("$1");
Update: Fixed to use double quotes instead of single quotes. Misread.
Update: Remove "or die("Expected value at pos ", pos(), "\n")" after the value extraction match. It'll never be executed since the pattern can match zero characters.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Help with regex for complicated key=value string
by mscharrer (Hermit) on Oct 29, 2008 at 19:22 UTC | |
by ikegami (Patriarch) on Oct 29, 2008 at 19:36 UTC | |
by mscharrer (Hermit) on Oct 29, 2008 at 19:43 UTC | |
by ikegami (Patriarch) on Oct 29, 2008 at 19:45 UTC |