X-Ftn-To: Greg Bacon
: I would like to match each value from @str with only one regex. I come
: to,
: if ( /="(.+?)"|=(\S+)/ ) { print $1 || $2 }
:
: but I'm not sure if this is the best matching solution?
How about the following?
It's fine but I was thinking about /alternative/ method for "match
everything between quotes OR match all consecutive non white chars". Since I
need this to parse html forms, I ended up with,
my $atr = qr/(?:["'](.*?)["']|([^>\s]+))/;
And here is the reinvented wheel with some known limitations(it doesn't
support group of checkboxes with same names).
=================================================
use strict;
my(%Q, $doc1);
{ local $/;
$doc1 = <DATA>;
}
$Q{IME} = 'user input';
$Q{_split} = ','; #for multiple select values
ParseForm(\$doc1);
print $doc1;
sub ParseForm {
##################################################
#
# popuni $$doc formu prema ulaznim parametrima
#
##################################################
use vars qw/%Q/;
my($doc, $i) = @_;
$doc ||= \$_;
$i ||= \%Q;
#atr regex
my $atr = qr/(?:["'](.*?)["']|([^>\s]+))/;
#text|hidden|password|checkbox|radio
$$doc =~ s{(<input.+?)(\s*/?>)}{
my($tag, $ending) = ($1, $2);
my $type = lc join'', $tag =~ /type=$atr/i;
if ($type) {
my $name = join'', $tag =~ /name=$atr/i;
my $value = $i->{$name};
#text|hidden|password
if ($type =~ /text|hidden|password/) {
$value = '' unless defined $value;
$value =~ s/"/"/g;
$tag =~ s/\s+value=$atr//i;
$tag .= qq{ value="$value"};
}
#checkbox|radio
elsif ($type =~ /checkbox|radio/) {
$tag =~ s/\s+checked//i;
if (($type eq 'checkbox' and defined $value) or
($tag =~ /value=$atr/i and ($1||$2) eq $value))
{
$tag .= ' checked';
}
}
}
"$tag$ending";
}iges;
#select|textarea
$$doc =~ s{(<(select|textarea).+?>)(.*?)(</\2>)}{
my($tag, $type, $cont, $ending) = ($1, lc $2, $3, $4);
my $name = join'', $tag =~ /name=$atr/i;
my $value = $i->{$name};
#textarea
if ($type eq 'textarea') { $cont = $value }
#select
else {
$cont =~ s/\s+selected(?=>)//ig;
my $split = $i->{'_split'};
my @vals = $split ? (split /$split/, $value) : $value;
$cont =~ s/(<[^>]+?=(?:["']$_["']|$_))/$1 selected/ for @vals;
}
"$tag$cont$ending";
}iges;
}
__DATA__
<form ....>
<input type=text name=IME size=50 maxlength=50 value="Default">
</form>