in reply to splitting on multiple delimiters
Rolled two ways to do it, in case just one page of code might be enlightening.
# Simple command argument extraction: sub grabArgs { my( $cmd )= @_; my @args; while( $cmd =~ m{ (?: ^ | \G ) # Don't skip any characters \s* # Skip leading whitespace (?: ([^\s"]+) # Non-space non-quotes are simple argument +s, capture | (") # Double-quoted string, capture it as $2 ( # Capture the inside as $3 (?: # Zero or more of the following \\. # Use \\ and \" to get \ and " inside quot +es | [^\\"]+ # Not \ nor " means just include it )* )" | ($) # End of string as $4 ) (?! \S ) # Arguments must be space-separated }xgc ) { return \@args if defined $4; push @args, $2 ? $3 : $1; $args[-1] =~ s/\\(.)/$1/g if $2; } substr( $cmd, pos($cmd), 0, "<ERROR>" ); die "Invalid command specification near '<ERROR>': $cmd\n"; } # Pretty much what Text::Shellwords does: sub parseArgs { my( $cmd )= @_; my @args; while( $cmd =~ m{ (?: ^\s* | \G ) (?: ($) # $1: End of string | (\s+) # $2: Whitespace | ([^\s\\"']+) # $3: Nothing special | '( [^']* )' # $4: 'string' | "( (?: \\. | [^\\"]+ )* )" # $5: "string" | \\ (.) # $6: \x escape ) }xgc ) { my( $end, $sp, $ns, $sq, $dq, $esc )= ( $1, $2, $3, $4, $5, $6 ); return \@args if defined $end; push @args, '' if ! @args; if( $sp ) { push @args, ''; } elsif( defined $ns ) { $args[-1] .= $ns; } elsif( defined $sq ) { $args[-1] .= $sq; } elsif( defined $dq ) { $dq =~ s/\\(.)/$1/g; $args[-1] .= $dq; } elsif( defined $esc ) { $args[-1] .= $esc; } else { die "Buggy code"; } } substr( $cmd, pos($cmd), 0, "<ERROR>" ); die "Invalid command specification near '<ERROR>': $cmd\n"; }
Interestingly, I had to go back to perl 5.005_03 in order to find a Perl that this works on. It appears to tickle bugs in Perl for several 5.8 and 5.6 versions. I might test on 5.10 tomorrow when I have a copy handy again.
- tye
|
|---|