my @array = split /(?=\breplace\s*\()/, 'chunk1 replace(123\) ) chunk3 "Hello replace me" more stuff'; my @lotsa_chunks; for my $bit (@array) { if ($bit =~ /^replace/) { # do careful stuff, on new chunk my $last = ''; my $re = ''; for (split //, $bit) { unless ( $_ eq ')' and $last ne "\\" ) { $re .= $_; $last = $_; next; } $re .= $_; # add closing bracket push @lotsa_chunks, $re; # push complete RE into a chunk $bit =~ s/\Q$re\E//; # hack RE off push @lotsa_chunks, chunk($bit); # chunk the remainder } } else { push @lotsa_chunks, chunk($bit); } } print "$_\n" for @lotsa_chunks; # this sub splits a function into quoted and unquoted chunks sub chunk { my $func = shift; my @chunks; my $chunk = 0; my $found_quote = ''; for (split //, $func) { # look for RE # look for opening quote if (/'|"/ and ! $found_quote) { $found_quote = $_; $chunk++; $chunks[$chunk] = $_; next; } # look for coresponding closing quote if ( $found_quote and /$found_quote/ ) { $found_quote = ''; $chunks[$chunk] .= $_; $chunk++; next; } # no quotes so just add to current chunk $chunks[$chunk] .= $_; } # strip whitespace from unquoted chunks; for (@chunks) { next if m/^(?:"|')/; # leave quoted strings alone s/^[ \t]+|[ \t]+$//g; } return @chunks; }