For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > November 2006 > Interpolation of backslash-escapes









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Interpolation of backslash-escapes
Peter Daum

2006-11-03, 6:57 pm

I am looking for an way to interpolate backslash-sequences
within a string with the usual perl semantics, e.g.
$s='1\t\2\t3\na\ b c' should become:
'1<tab>2<tab>3
a b c'

Things I tried were for example
$s= eval('' . "$val"); # (hoping to trigger the normal interpolation) or
$s=~ s/\\(.)/"\\$1"/eg;
but somehow i couldn't get it right ...

Can anybody think of an elegant solution?

Regards,
Peter Daum

D. Bolliger

2006-11-03, 6:57 pm

Peter Daum am Freitag, 3. November 2006 20:26:

Hoi Peter,

> I am looking for an way to interpolate backslash-sequences
> within a string with the usual perl semantics, e.g.
> $s='1\t\2\t3\na\ b c' should become:
> '1<tab>2<tab>3
> a b c'


With usual perl semantics, the result is different :-)

> Things I tried were for example
> $s= eval('' . "$val"); # (hoping to trigger the normal interpolation) or
> $s=~ s/\\(.)/"\\$1"/eg;
> but somehow i couldn't get it right ...
>
> Can anybody think of an elegant solution?


I think there are more elegant solutions, but in the following you have full
control over what translates to what:

#!/usr/bin/perl

use strict;
use warnings;

my %trans=(
'\t'=>"\t",
'\n'=>"\n",
'\ '=>' ',
'\2'=>'2',
q(\\)=>qw( \ ), # ;-)
);

my $s='1\t\2\t3\na\ b c \\\ '; # last space: ;-)

$s=~s; (\\.) ; $trans{$1} || $1 ;gex;

print "<$s>\n";

# Note "the usual perl semantics":
print "<\2><\ >\n";

__END__

Dani
Tom Phoenix

2006-11-03, 6:57 pm

On 11/3/06, Peter Daum <gator_ml@yahoo.de> wrote:

> I am looking for an way to interpolate backslash-sequences
> within a string with the usual perl semantics


That's what eval does, although you have to build your string with
care. Don't let the user put their own data into that string; they can
(accidentally or intentionally) crash your program or worse, if you
use eval.

A better way would be to interpolate only the sequences that you need
to support. I'd write a subroutine to do that, returning the converted
string. It's simple to loop over the input string and build the new
string as you go, and it completely avoids the riskiness of eval.

Hope this helps!

--Tom Phoenix
Stonehenge Perl Training
Rob Dixon

2006-11-03, 6:57 pm

Peter Daum wrote:
>
> I am looking for an way to interpolate backslash-sequences
> within a string with the usual perl semantics, e.g.
> $s='1\t\2\t3\na\ b c' should become:
> '1<tab>2<tab>3
> a b c'
>
> Things I tried were for example
> $s= eval('' . "$val"); # (hoping to trigger the normal interpolation) or
> $s=~ s/\\(.)/"\\$1"/eg;
> but somehow i couldn't get it right ...
>
> Can anybody think of an elegant solution?


eval "qq($val)";

But note that the "\2" in your string (I don't know if it's a typo) will become
a character with an octal value of 2, i.e. the ASCII STX control character.

HTH,

Rob
John W. Krahn

2006-11-03, 6:57 pm

Peter Daum wrote:
> I am looking for an way to interpolate backslash-sequences
> within a string with the usual perl semantics, e.g.
> $s='1\t\2\t3\na\ b c' should become:
> '1<tab>2<tab>3
> a b c'
>
> Things I tried were for example
> $s= eval('' . "$val"); # (hoping to trigger the normal interpolation) or
> $s=~ s/\\(.)/"\\$1"/eg;
> but somehow i couldn't get it right ...
>
> Can anybody think of an elegant solution?


$ perl -le'
my %translate = (
t => "\t",
n => "\n",
r => "\r",
f => "\f",
b => "\b",
a => "\a",
e => "\e",
);
my $s = q[1\t\2\t3\na\ b c];
print $s;
$s =~ s/\\(.)/ exists $translate{ $1 } ? $translate{ $1 } : $1 /seg;
print $s;
'
1\t\2\t3\na\ b c
1 2 3
a b c



John
--
Perl isn't a toolbox, but a small machine shop where you can special-order
certain sorts of tools at low cost and in short order. -- Larry Wall
Rob Dixon

2006-11-03, 6:57 pm

Rob Dixon wrote:
>
> Peter Daum wrote:
>
> eval "qq($val)";
>
> But note that the "\2" in your string (I don't know if it's a typo) will
> become
> a character with an octal value of 2, i.e. the ASCII STX control character.


I need to add that that solution relies on any parentheses in the string being
in matching pairs. If you try

$val = ')(';

then it just won't work. If that's a problem, then you can use different
delimiters, which are guaranteed to be either escaped or not in the string at
all. The tilde is a useful one:

eval "qq~$val~";

or if you're relaly stuck, then any character at all will do, including control
characters:

eval "qq\0$val\0";

works fine and delimits the string with null characters,

Cheers,

Rob

Randal L. Schwartz

2006-11-04, 3:56 am

>>>>> "Rob" == Rob Dixon <rob.dixon@350.com> writes:[color=darkred]

Rob> eval "qq($val)";

s/elegant/hacky, dangerous, broken/

Consider $val = "), $yourcode_here, (".

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Rob Dixon

2006-11-04, 6:56 pm

Randal L. Schwartz wrote:
>
> Rob> eval "qq($val)";
>
> s/elegant/hacky, dangerous, broken/
>
> Consider $val = "), $yourcode_here, (".


Old news, out of context, petulant.

Rob
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com