perl regular expression

K

kiranmn

hi,

I want all doublequote in a string to be prefixed with '\'. I want
to achive this with a regular expression and this regular expression
will be in a loop, so for the same input if this same RE runs multiple
times, it will add multiple '\` before doublequote, to avoid that i
am checking for " NOT A BACKSLASH" in following RE.

Following RE works for me, but it fails for two consecutive
doublequotes.
Why RE is failing to replace second double quote, even with /g ?

regards,
kiran

------------------------------------------
Expect output
input is abc "" c " de
output is abc \"\" c \" de
------------------------------------------
current output
input is abc "" c " de
output is abc \"" c \" de
=========================
$input='abc "" c " de';
print "input is $input\n";;
$input=~ s/([^\\x])"/$1\\"/g;
print "output is $input\n";;
============================
 
M

Mirco Wahab

I want all doublequote in a string to be prefixed with '\'. I want
to achive this with a regular expression and this regular expression
will be in a loop, so for the same input if this same RE runs multiple
times, it will add multiple '\` before doublequote, to avoid that i
am checking for " NOT A BACKSLASH" in following RE.

Following RE works for me, but it fails for two consecutive
doublequotes.
Why RE is failing to replace second double quote, even with /g ?

You modifying the string contents of
character positions to match in the
next run of /g. By one \\ each time.

So you may go back in the match position
by one on each /g step:

...

while ($input =~ s/([^\\x])"/$1\\"/g) {
pos($input)--;
}

...


BTW. what does the 'x' in the
character class mean?

Regards

M.
 
M

Mirco Wahab

I want all doublequote in a string to be prefixed with '\'. I want
to achive this with a regular expression and this regular expression
will be in a loop, so for the same input if this same RE runs multiple
times, it will add multiple '\` before doublequote, to avoid that i
am checking for " NOT A BACKSLASH" in following RE.

Following RE works for me, but it fails for two consecutive
doublequotes.
Why RE is failing to replace second double quote, even with /g ?

You are modifying the string contents of character positions
for the next match by one \\ each time.

You could go back in the match position
by one on each match or simply match
successively:

...

1 while $input =~ s/([^\\x])"/$1\\"/g;

...


BTW. what does the 'x' in the
character class mean?

Regards

M.
 
M

Mirco Wahab

Mirco said:
...

1 while $input =~ s/([^\\x])"/$1\\"/g;

...

Of course, if your whole problem is
to escape quotes which aren't quoted
already, you could do a "double magical"

$input =~ s|(?<!\\)(?=")|\\|g;

which combines two zero-width assertions

(?<!\\) ==> not a \\
(?=") ==> before a quote

and replaces that 'cleft' by a \\

Regards

M.
 
D

Dr.Ruud

(e-mail address removed) schreef:
Following RE works for me, but it fails for two consecutive
doublequotes.
Why RE is failing to replace second double quote, even with /g ?

$input='abc "" c " de';
print "input is $input\n";;
$input=~ s/([^\\x])"/$1\\"/g;
print "output is $input\n";;

You could use

1 while $input =~ s/([^\\x])"/$1\\"/;

but that would go wrong for a " at the start anyway.

This way is much clearer:

#!/usr/bin/perl
use strict;
use warnings;

my $input = q{"abc "\\" c " de};
print qq{input is $input\n};

for (1..4) {
$input =~ s# (?<! \\ ) " #\\"#xg;
print qq{output is $input\n};
}
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top