Re: reverse quotemeta?
by japhy (Canon) on Jun 26, 2001 at 20:04 UTC
|
You're asking, "how can I generally turn escape sequences into what they correspond to", right?
### updated (thanks, Abigail)
### Unicode NOT included
sub expand_escapes {
local $_ = shift;
s{
(
\\
(?:
x[A-Fa-f0-9]{0,2} # hex escape
|
0[0-7]{0,3} # octal escape
|
c. # ctrl-escape
|
. # any other
)
)
}{qq["$1"]}geexs;
return $_;
}
japhy --
Perl and Regex Hacker | [reply] [d/l] |
|
| [reply] |
|
In Perl's double quoted strings, octal escapes don't need
a leading zero.
japhy, please don't make silent updates to your
node. (I'm used to update notes using bold)
(updated)
-
tye
(but my friends call me "Tye")
| [reply] |
|
Yeah, if only things were so simple.
"\0001" is one character according to
your subroutine. However, Perl thinks it's two. As
tye pointed out, leading 0s aren't
required (but allowed). But for octets above 077
a leading 0 doesn't seem to be allowed. And
for octets above 377, you will
move into Unicode territory, whether you want it or not.
"\400" causes Perl to think things are really
messed up.
-- Abigail
| [reply] [d/l] [select] |
Re: reverse quotemeta?
by suaveant (Parson) on Jun 26, 2001 at 19:39 UTC
|
$x =~ s/(?<!\\)\\n/\n/g;
the (?<!\\) is to make sure the \ in \n isn't escaped.
- Ant | [reply] [d/l] |
|
| [reply] [d/l] |
|
s#(?<!\\)((?:\\\\)*)\\n# '\\'x(length($1)/2) . "\n" #ge;
# or
s#(?<!\\)(\\*)\1\\n#$1\n#g;
I find that having to escape your backslashes only when
they preceed a (desired) newline to be confusing so I'd
go with japhy's excellent sugestion or perhaps:
s#\\([\\n])# $1 eq "n" ? "\n" : $1 #ge
-
tye
(but my friends call me "Tye") | [reply] [d/l] [select] |
Re: reverse quotemeta?
by Hofmator (Curate) on Jun 26, 2001 at 19:38 UTC
|
$x = '\n';
$x =~ s/(?<!\\)\\n/\n/g;
print $x;
Update: Well, I was first but I had to pay my price :) - as suaveant correctly pointed out, you have to take care of the special case of an escaped escape so I fixed that.
What would be interesting is a simple general solution which does that transformation not only for \n but also \t, \cC, \xFF, ... but I'm lost there. Anybody??
-- Hofmator
| [reply] [d/l] |
Re: reverse quotemeta?
by chromatic (Archbishop) on Jun 26, 2001 at 23:21 UTC
|
Not the best general solution, but at least I don't have to write a nasty regex:
my $x = '\n';
my $string = '$x = "' . qq|$x| . '";';
eval $string;
print "->$x<-\n";
It's missing error handling and if $x contains any unescaped single quotes, it'll break. Still, it's another way to do it. | [reply] [d/l] |
Re: reverse quotemeta?
by nardo (Friar) on Jun 26, 2001 at 19:39 UTC
|
This isn't a reverse quotemeta since quotemeta won't turn a newline into '\n'
eval("\$x = \"$x\"");
should do what you want.
Update This is not ideal, although this will perform all escaped character conversions, if your string has an unescaped '$' in it then it will be replaced by a variable. For example: 'It costs $1.25' the '$1' will be replaced with the contents of $1 | [reply] [d/l] |
Re: reverse quotemeta?
by RatArsed (Monk) on Jun 26, 2001 at 19:54 UTC
|
$x =~ s/\\n/\n/gi;
I'm sure there's a better way to do it using tr///, but my brain is fried for today...
--
RatArsed | [reply] [d/l] |
|
I don't think that's correct.
tr/// can only do character-by-character substitutions, so \n as an escaped new line would be 2.
You'd also have to consider any other extenuating circumstances, like having an escaped slash preceding a normal n.
Update
So this perl hacker walks into a bar...
and says "ouch!"
thank you all.
| [reply] [d/l] [select] |