Re: Substituting literal strings for escape characters
by valdez (Monsignor) on Feb 18, 2003 at 13:31 UTC
|
| [reply] |
Re: Substituting literal strings for escape characters
by jmcnamara (Monsignor) on Feb 18, 2003 at 13:46 UTC
|
#!/usr/bin/perl -wl
use strict;
my %esc = (
'\0' => "\0",
'\a' => "\a",
'\b' => "\b",
'\t' => "\t",
'\n' => "\n",
'\v' => "\013",
'\f' => "\f",
'\r' => "\r",
);
my $literal = 'aaa\tbbb\nccc\tddd\t\\\\end';
(my $escaped = $literal) =~ s/(\\.)/exists $esc{$1} ? $esc{$1} : $
+1/eg;
print $literal, "\n";
print $escaped;
__END__
Prints:
aaa\tbbb\nccc\tddd\t\\end
aaa bbb
ccc ddd \\end
Backslash has to be escaped in single quoted strings so it doesn't require a substitution.
The escape characters shown are the usual shell escapes. Perl adds a few more such as \e. Note the exists() isn't strictly required.
--
John.
| [reply] [d/l] |
|
|
| [reply] |
Re: Substituting literal strings for escape characters
by steves (Curate) on Feb 18, 2003 at 13:46 UTC
|
my $x = '\t\t\n\t\n\n';
eval "\$x = \"$x\"";
print "$x";
| [reply] [d/l] |
|
|
Just for fun, try that with:
my $x = '";warn q[this is code!] for 1..20;"';
:-)
Hint: Don't use eval() carelessly... your version allows arbitrary code to be placed in the input string, which will get executed | [reply] [d/l] |
|
|
| [reply] |
Re: Substituting literal strings for escape characters
by Tomte (Priest) on Feb 18, 2003 at 13:32 UTC
|
perl -e "\$test='a\n\nb'; \$test =~ s/(\\\\\\w)/pack(\"h\",\"\$1\")/ge
+;print \$test"
yields
a
b
Notice that there is a blank in front of the b
I don't know where the blank originates from, but to use pack seems to be starting point
hth
Update:pure luck that it kind of worked with \n, basically b***sh*t.
Update II:I was asked to beep 'the word' out, so that corporate filters don't choke on this node. I'm in no way expecting anybody in here to be offended by it :-)
regards,
tomte
| [reply] [d/l] [select] |
Re: Substituting literal strings for escape characters
by hv (Prior) on Feb 18, 2003 at 13:57 UTC
|
You are going in the right direction with the evalled substitution, but consider what you end up with: eval "\n", which is much the same as
eval {
}
The obvious next thing to try is adding the quotes:
s/(\\\w)/"$1"/eg;
but that doesn't do the trick, and brainfade prevents me from explaining why. :(
Adding a second evaluation step is enough to achieve the desired result:
s/(\\\w)/qq{"$1"}/eeg;
Hugo | [reply] [d/l] [select] |
|
|
That contains a bug:
The input string: \\n
should be interpreted as: \n
(as in, the backslash escapes the backslash) but in your case, it becomes a backslash followed by a newline.
The solution is: s/(\\.)/qq["$1"]/eegs
Btw, the reason "$1"/e isn't sufficient is because when using /e it doesn't interpolate before evaluating, so the expression really becomes "$1" which is identical to $1 - no change happens at all.
With qq["$1"]/ee however it'll interpolate $1 into a double-quoted string the first time, and then evaluates that double-quoted string
•Update: to also support multi-char escapes:
s/(\\(?:\d{1,3}|x[a-fA-F\d]{1,2}|x\{\w*\}|c.|N\{\w*\}|.))/qq["$1"]/eeg
+s
(not fully tested) | [reply] [d/l] [select] |
Re: Substituting literal strings for escape characters
by JamesNC (Chaplain) on Feb 18, 2003 at 18:18 UTC
|
I wrote this a while ago... hope it helps.. you can use it as a package or just copy the sub..
package Escape;
use Exporter;
# simple escape module for html stuff
# use Escape;
# my $data = escape($string_to_escape);
@ISA = qw(Exporter);
@EXPORT = qw(escape);
sub escape {
my $data = shift;
$data =~ s/\%/%25/g;$data =~ s/\t/%9/g;$data =~ s/\n/A/g;
$data =~ s/ /%20/g;$data =~ s/\!/%21/g;$data =~ s/\"/22/g;
$data =~ s/\#/%23/g;$data =~ s/\$/24/g;$data =~ s/\&/%26/g;
$data =~ s/\'/%27/g;$data =~ s/\(/%28/g;$data =~ s/\)/%29/g;
$data =~ s/\*/%2A/g;$data =~ s/\+/%2B/g;$data =~ s/\,/%2C/g;
$data =~ s/\-/%2D/g;$data =~ s/\./%2E/g;$data =~ s/\//%2F/g;
$data =~ s/\:/%3A/g;$data =~ s/\;/%3B/g;$data =~ s/\</%3C/g;
$data =~ s/\=/%3D/g;$data =~ s/\>/%3E/g;$data =~ s/\?/%3F/g;
$data =~ s/\@/%40/g;$data =~ s/\[/%5B/g;$data =~ s/\\/%5C/g;
$data =~ s/\]/%5D/g;$data =~ s/\^/%5E/g;$data =~ s/\_/%5F/g;
$data =~ s/\`/%60/g;$data =~ s/\{/%7B/g;$data =~ s/\|/%7C/g;
$data =~ s/\}/%7D/g;$data =~ s/\~/%7E/g;
return $data;
}
1;
Cheers,
James | [reply] [d/l] |
|
|
it was pointed out to me that I was way off the mark.. sorry...
perhaps this little snippet will give you something to experiment with that may provide you with the insight you are hoping to find
use strict;
#Experiment with commenting out the next line!
binmode STDIN, ":raw";
print "Just hit the enter key!\n";
my $char = <STDIN>;
my $bits = unpack "B*", $char;
print "[Enter]'ed bits: $bits \n";
my $bits = unpack "B*", '\n';
print "The literal bits: $bits \n";
| [reply] [d/l] |
Re: Substituting literal strings for escape characters
by Anonymous Monk on Feb 18, 2003 at 22:57 UTC
|
Code:
$x = '\n';
print "var :==$x==\n";
print "eval :==",
eval( qq{ sprintf "%s","$x" } ),
"==\n";
Output:
var :==\n==
eval :==
==
You need double-quotish interpolation *twice*. :) | [reply] |