String escaping

R

RedGalaxy UK

Help!!

I'm rather new to Perl; trying it out as it has advantages over PHP in
the things I want to do.

In PHP there is a simple function, addslashes(), which changes ' for
\', " for "\, \ for \\ and so on (basically adding a backslash to
escape it).

Trying to do the same in Perl and can't find any way to do the \ = \\
change? Found this little sub:

sub addslashes {
my $string = shift;
$string=~s/'/\\'/g;
$string=~s/"/\\"/g;

return $string;
}

If I pass it something like:

This is just a 'dummy test' and it works.

It will give me:

This is just a \'dummy test\' and it works.

However, parts of my data will include backslashes in the data itself,
and if I try passing something like:

C:\Windows\System\

It will print:

C: indows ystem

Anybody know how I could do this, or even if there is a function within
Perl I just don't know about? I'm using ActiveState's ActivePerl 5.8.7
for Windows.

Thanks.

Paul
 
A

A. Sinan Unur

Help!!

I'm rather new to Perl; trying it out as it has advantages over PHP in
the things I want to do.

In PHP there is a simple function, addslashes(), which changes ' for
\', " for "\, \ for \\ and so on (basically adding a backslash to

"\ ?
escape it).

What determines which characters are escaped?

I sense an X-Y problem here: You want to achieve X, you think Y is the
way to do it, and therefore you are asking about Y.

What is X in your case?

Sinan
 
J

John W. Krahn

RedGalaxy said:
I'm rather new to Perl; trying it out as it has advantages over PHP in
the things I want to do.

In PHP there is a simple function, addslashes(), which changes ' for
\', " for "\, \ for \\ and so on (basically adding a backslash to
escape it).

Trying to do the same in Perl and can't find any way to do the \ = \\
change?

my $newstring = quotemeta $oldstring;

my $newstring = "\Q$oldstring\E";


perldoc -f quotemeta
perldoc perlop


John
 
T

Tad McClellan

RedGalaxy UK said:
In PHP there is a simple function, addslashes(), which changes ' for
\', " for "\, \ for \\ and so on (basically adding a backslash to
escape it).

C:\Windows\System\


Just in case you didn't know this, you can probably use

C:/Windows/System/

with no ill effects.

As long as the filename is not fed to the command interpreter,
(like from within a Perl program) you can use forward slashes
instead of backwards slashes.
 
R

RedGalaxy UK

The only problem with this is that the text passed to the database
might not necessarily be a file path. People are using a website where
they post entries, comments, messages, etc, and my perl script is
basically processing this information and inserting data into a
database on my company data server, so it could be a string of random
text where they insert a backslash into it.

Paul
 
R

RedGalaxy UK

Hi John,

I just tried those; it seems to be escaping anything which isn't an
alphanumeric character, but failed to do anything about the backslashes
in the original string. :(

Paul
 
R

RedGalaxy UK

A. Sinan Unur,

I'm determining which characters are escaped with the separate lines in
the sub:

sub addslashes {
my $string = shift;
$string=~s/'/\\'/g;
$string=~s/"/\\"/g;

return $string;
}

That's currently looking for instances of ' and " and escaping those,
and my thought, or "Y" as you put it, was that if I added

$string=~s/\/\\\/g;

it would escape any backslashes already in the string. However I get an
error, trailing backslash in regex. "X" in this case is trying to get
the script to escape backslashes in a string, so for example if I had
"Tomatoes\Apples\Pears\Fruits" it'll change it to
"Tomatoes\\Apples\\Pears\\Fruits"

It would be so much easier if this was data I could control but it's
from a large member-controlled site.

Does this help you to understand my situation better?

Thanks.

Paul
 
A

A. Sinan Unur

A. Sinan Unur,

I'm determining which characters are escaped with the separate lines
in the sub:

It would be much easier to follow the discussion if you quoted an
appropriate amount of context.

....
That's currently looking for instances of ' and " and escaping those,
and my thought, or "Y" as you put it, was that if I added

That still does not explain what the "Y" is: I have a feeling you think
all this slash stuff is necessary for dealing with paths, but it is not.

See File::Spec.
$string=~s/\/\\\/g;

it would escape any backslashes already in the string. However I
get an error, trailing backslash in regex.

Here is a naive implementation:

#!/usr/bin/perl

use strict;
use warnings;

my $s = q{'"Sin} . q{\\} . q{an"'};

print "$s\n";
print my_escape($s);

sub my_escape {
my ($s) = @_;
$s =~ s{(['"\\])}{\\$1}g;
return $s;
}

__END__

By the way, I would be using quotemeta for this particular purpose:

perldoc -f quotemeta

On the other hand, if you are jumping through these hoops to deal with
Win32 paths, it is not necessary.

Sinan
 
T

Tad McClellan

RedGalaxy UK said:
$string=~s/\/\\\/g;

it would escape any backslashes already in the string.
so for example if I had
"Tomatoes\Apples\Pears\Fruits" it'll change it to
"Tomatoes\\Apples\\Pears\\Fruits"


Both the pattern and the replacement string part of s///
are "double quotish", they act like double quoted strings.

You need to backslash each backslash in your code in order
to backslash each backslash in your data. :)

$string =~ s/\\/\\\\/g;
 
R

RedGalaxy UK

Tad,

Just tried this; for some reason it doesn't seem to work :-( If I
change the string to Apples\Bananas\Pears, it comes up with
ApplesBananasPears and for some reason completely removes the
backslashes before the string is passed to anything else.

Paul
 
R

RedGalaxy UK

Tried $string =~ s/\\/\\\\/g; and not working.

I added the

use warnings;

as you said. It's come up with the following:

Unrecognized escape \P passed through at D:\Files\Perl Scripts\test.pl
line 3
Unrecognized escape \B passed through at D:\Files\Perl Scripts\test.pl
line 3

Line 3 in this case is:

$name="Apples\Pears\Bananas";

Paul
 
R

RedGrittyBrick

RedGalaxy said:
Tad,

Just tried this;

FFS. Tried what? Please read
http://groups.google.com/googlegroups/posting_style.html#summarize
for some reason it doesn't seem to work :-( If I
change the string to Apples\Bananas\Pears, it comes up with
ApplesBananasPears and for some reason completely removes the
backslashes before the string is passed to anything else.
type quoteslash.pl
#!perl
use warnings;
use strict;

my $text = 'Tomatoes\Apples\Pears\Fruits';
print "Before: $text\n";
$text =~ s/\\/\\\\/g;
print "After: $text\n";
quoteslash.pl
Before: Tomatoes\Apples\Pears\Fruits
After: Tomatoes\\Apples\\Pears\\Fruits
 
T

Tad McClellan

RedGalaxy UK said:
Tad,

Just tried this;


Tried what?

Please quote some context in your followups like everybody else does.

Please post a short and complete program *that we can run* that
illustrates the problem you are having.

for some reason it doesn't seem to work :-( If I
change the string to Apples\Bananas\Pears,


How did you "change the string"?

You must show us your code if we are to debug your code.

Have you seen the Posting Guidelines that are posted here frequently?

it comes up with
ApplesBananasPears and for some reason


Did you "change the string" by using double quotes in your source code?

completely removes the
backslashes before the string is passed to anything else.


Post real code if you want real help.

Shotgunning a bunch of guesses is not an efficient use of time.
 
J

Jürgen Exner

RedGalaxy said:
Just tried this; for some reason it doesn't seem to work :-( If I

What did you try? Please quote some context -as has been customary for two
decades!- such that people have a chance to know what you are talking about.
change the string to Apples\Bananas\Pears, it comes up with

What string did you want to change to 'Apples\Bananas\Pears'?

jue
 
R

RedGalaxy UK

Tried what you suggested perhaps?
Have you seen the Posting Guidelines that are posted here frequently?

No I haven't seen the posting guidelines; I'm new to newsgroups. Never
used them before.
Did you "change the string" by using double quotes in your source code?

The string is in a double-quoted variable:

$name="Apples\Bananas\Pears";
Post real code if you want real help.

I have already posted the code several times.
 
R

RedGalaxy UK

type quoteslash.pl
Before: Tomatoes\Apples\Pears\Fruits
After: Tomatoes\\Apples\\Pears\\Fruits

Thanks. That worked. Just got to remember to put the string into single
quotes rather than double.
 
T

Tad McClellan

RedGalaxy UK said:
Tried what you suggested perhaps?


No I haven't seen the posting guidelines; I'm new to newsgroups. Never
used them before.


You should go find them then.

They greatly increase the chances of getting a useable answer while
decreasing the amount of back-and-forth required to understand
the problem.

The string is in a double-quoted variable:

$name="Apples\Bananas\Pears";


( you should always enable warnings when developing Perl code, it
would have said something about that line...
)

That is the _first_ time you have posted that code. Add this:

print "name is '$name'\n";

to see if you have what you think you have.

Then change it to:

$name='Apples\Bananas\Pears'; # single quotes don't eat backslashes

or

$name='Apples/Bananas/Pears';

I have already posted the code several times.
^^^^^^^^

You posted "some code", not "the code" that assigns to $name.

You never showed the string to be matched against in code, only in prose.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top