5

In perl suppose I have a string like 'hello\tworld\n', and what I want is:

'hello  world
'

That is, "hello", then a literal tab character, then "world", then a literal newline. Or equivalently, "hello\tworld\n" (note the double quotes).

In other words, is there a function for taking a string with escape sequences and returning an equivalent string with all the escape sequences interpolated? I don't want to interpolate variables or anything else, just escape sequences like \x, where x is a letter.

2 Answers 2

8

Sounds like a problem that someone else would have solved already. I've never used the module, but it looks useful:

use String::Escape qw(unbackslash);
my $s = unbackslash('hello\tworld\n');
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks very much for this. I found String::Interpolate, but that does something completely different.
Also, for people using this in Ubuntu 9.10, the version of String::Escape doesn't have unbackslash. Instead it has unprintable.
2

You can do it with 'eval':

my $string = 'hello\tworld\n';
my $decoded_string = eval "\"$string\"";

Note that there are security issues tied to that approach if you don't have 100% control of the input string.

Edit: If you want to ONLY interpolate \x substitutions (and not the general case of 'anything Perl would interpolate in a quoted string') you could do this:

my $string = 'hello\tworld\n';
$string =~ s#([^\\A-Za-z_0-9])#\\$1#gs;
my $decoded_string = eval "\"$string\"";

That does almost the same thing as quotemeta - but exempts '\' characters from being escaped.

Edit2: This still isn't 100% safe because if the last character is a '\' - it will 'leak' past the end of the string though...

Personally, if I wanted to be 100% safe I would make a hash with the subs I specifically wanted and use a regex substitution instead of an eval:

my %sub_strings = (
    '\n' => "\n",
    '\t' => "\t",
    '\r' => "\r",
);

$string =~ s/(\\n|\\t|\\n)/$sub_strings{$1}/gs;

3 Comments

Can I use a combination of eval and quotemeta to do this safely? Basically, (my $interpolated_string = eval(q(") . quotemeta($string) . q("))) =~ s/\\(.)/\1/g.
Not without it killing the interpolation as well. ;)
Well, I only want to interpolate \x, where x is any letter. Not variables or other stuff.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.