in reply to Replace only unescaped metachars

It can be done (at least approximated) in a somewhat more traditional s///g manner, but I'd use two substitutions to deal first with metacharacters, then unescaping.
my $escape = qr/(?<!\\)\\/; my $meta_char = qr/(?<!$escape)[?*]/; no warnings 'qw'; my %meta = qw( ? # * ? ); my $result = my $string = 't?e\\\\xt\\\\* with e\\scapes\\*'; $result =~ s/($meta_char)/$meta{ $1}/g; $result =~ s/$escape(.)/$1/gs or die; print "$string\n"; print "$result\n";
It transforms the example string in the same way as your code. I wouldn't swear that it does for all input strings.

Anno

Replies are listed 'Best First'.
Re^2: Replace only unescaped metachars
by ikegami (Patriarch) on Feb 22, 2007 at 17:53 UTC
    Close, but no cigar
    my $string = '\\\\\\a'; # Unprocessed: \\\a # Should be: \a # Result: \\a
    my $string = '\\\\\\?'; # Unprocessed: \\\? # Should be: \? # Result: \\#

    See my top-level reply for a solution.

      Yes, I knew it had limitations which are hard to fix in an s/// approach.

      The recognition of escaped escapes is a naturally recursive problem. Regular expressions, even Perl's, are notoriously bad at that. Your remark about wanting a parser is spot on.

      Anno

        There's no recursion here (which is why the OP's parser is really just a tokeniser). The problem is capturing repeatedly, and knowing which rule (regexp piece) captured a given capture.