I thought it might be interesting to benchmark the various solutions:
#!/usr/bin/env perl
use warnings;
use strict;
use Benchmark qw/cmpthese/;
use JSON::PP ();
use Cpanel::JSON::XS ();
my $IN = '"654321_1111"';
my $EXP = '654321_1111';
use constant TEST=>0;
print "Testing is ", TEST?"enabled":"disabled", "\n";
my $json_pp = JSON::PP->new->allow_nonref;
my $json_xs = Cpanel::JSON::XS->new->allow_nonref;
cmpthese(-2, {
regex_strip => sub { # GrandFather
(my $out = $IN) =~ s/^"|"$//g;
$out eq $EXP or die $out if TEST;
},
regex_match => sub { # BillKSmith
my ($out) = $IN =~ /^\"(.+)\"$/;
$out eq $EXP or die $out if TEST;
},
tr_strip => sub { # kcott and hippo
(my $out = $IN) =~ y/"//d;
$out eq $EXP or die $out if TEST;
},
substr => sub { # syphilis and AnomalousMonk
my $out = substr $IN, 1, -1;
$out eq $EXP or die $out if TEST;
},
reverse => sub { # rsFalse
my $out = $IN;
for (1..2) {
$out = reverse $out;
chop $out;
}
$out eq $EXP or die $out if TEST;
},
json_pp => sub { # haukex
my $out = $json_pp->decode($IN);
$out eq $EXP or die $out if TEST;
},
json_xs => sub { # haukex
my $out = $json_xs->decode($IN);
$out eq $EXP or die $out if TEST;
},
});
__END__
Testing is disabled
Rate json_pp regex_strip regex_match reverse json_xs
+ tr_strip substr
json_pp 161266/s -- -85% -96% -96% -97%
+ -97% -99%
regex_strip 1081962/s 571% -- -73% -74% -81%
+ -81% -91%
regex_match 3989148/s 2374% 269% -- -2% -29%
+ -30% -67%
reverse 4091430/s 2437% 278% 3% -- -28%
+ -28% -66%
json_xs 5654082/s 3406% 423% 42% 38% --
+ -0% -53%
tr_strip 5663601/s 3412% 423% 42% 38% 0%
+ -- -53%
substr 12107824/s 7408% 1019% 204% 196% 114%
+ 114% --
However, it's also very noteworthy that all of the solutions have their caveats, as already highlighted by AnomalousMonk and hippo:
- regex_strip will also remove unbalanced quotes, as in q{"foo} becomes q{foo}
- regex_match will also remove quotes from things that - depending on your input format - may not be syntactically valid, like q{"foo"bar"} becomes q{foo"bar}
- tr_strip will remove all quotes in the string no matter where they appear, i.e. q{"foo""bar"} becomes q{foobar}
- substr and reverse will remove the first and last character unconditionally, i.e. q{foobar} becomes q{ooba}
- json_pp and json_xs only apply if the input format is actually JSON or something that can be parsed as if it were, e.g. they will refuse to parse q{"foo"bar"}
This underscores what others have already said: it would be better if you could better specify your input format.