I think this (funcb) does what you want.
#!/usr/bin/perl
use warnings;
use strict;
my %CSV = ('n' => 'n',
't' => 't',
'f' => 'f',
'\\' => '\\',
);
my %CSV1 = ('\\n' => '\\n',
'\\t' => '\\t',
'\\f' => '\\f',
'\\\\' => '\\\\',
);
my @same = qw( \\ \\\\ a ab \a \a\b \a\n \n\a \n\n abc\a abc\\a );
my @diff = qw( a\\ \a\\ abc\a\\ abc\a\\\\ \a\b\c\d\e\x\g\h\\ );
print "These are the same as your function\n";
runtests(@same);
print "These are different:\n";
runtests(@diff);
sub runtests {
for my $in (@_) {
print " in: $in\n";
$_ = $in;
funca();
print " funca: $_\n";
my $savea = $_;
$_ = $in;
funcb();
printf " funcb: %-30s %s\n\n", $_, $_ eq $savea ? "SAME" : "DIF
+FERENT";
}
}
sub funca {
my $pos = 0;
while (m/\\(.)/g) { $pos=pos($_);}
s/\\(.)/exists($CSV{$1}) ? "\\$1" : "\\\\$1"/ge;
s/^(.{$pos})\\$/$1\\\\/;
}
sub funcb {
my $out = "";
pos($_) = 0;
s/\G(\\.|[^\\]+|\\$)/substr($1,0,1) eq '\\' ? $CSV1{$1} || "\\$1" :
+$1/eg;
}
__END__
# output:
These are the same as your function
in: \
funca: \\
funcb: \\ SAME
in: \\
funca: \\
funcb: \\ SAME
in: a
funca: a
funcb: a SAME
in: ab
funca: ab
funcb: ab SAME
in: \a
funca: \\a
funcb: \\a SAME
in: \a\b
funca: \\a\\b
funcb: \\a\\b SAME
in: \a\n
funca: \\a\n
funcb: \\a\n SAME
in: \n\a
funca: \n\\a
funcb: \n\\a SAME
in: \n\n
funca: \n\n
funcb: \n\n SAME
in: abc\a
funca: abc\\a
funcb: abc\\a SAME
in: abc\a
funca: abc\\a
funcb: abc\\a SAME
These are different:
in: a\
funca: a\
funcb: a\\ DIFFERENT
in: \a\
funca: \\a\
funcb: \\a\\ DIFFERENT
in: abc\a\
funca: abc\\a\
funcb: abc\\a\\ DIFFERENT
in: abc\a\\
funca: abc\\a\\\
funcb: abc\\a\\ DIFFERENT
in: \a\b\c\d\e\x\g\h\
funca: \\a\\b\\c\\d\\e\\x\\g\\h\
funcb: \\a\\b\\c\\d\\e\\x\\g\\h\\ DIFFERENT
NT