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
|
|
|
|
|