s/// does not affect pos?

F

Florian Kaufmann

Simplified to the basics I have the following problem: I want to
replace occurrences of double or single quoted strings in a text file.
The following shows what I want to get.

$ cat MyFile
foo "D'Quote" bar 'S"Qu
ote'

$ MyScript < MyFile
foo \begin{YasDQ}"D'Quote"\end{YasDQ} bar \begin{YasSQ}'S"Qu
ote'\end{YasSQ}

As you can see, the quotes have now new strings (in this example latex
commands) around them. Also note that a single quote within a double
quote is not a meta character anymore, and vice versa. Newlines must
not be treated special.

That's what I tried: It basically searches the next quote. From the
found position onwards it replaces the text up to the next matching
quote. It doesn't work however. I assume mainly because s/// does not
change pos($_) as m// does. I think I just need to know how to
accomplish that after something like s/regex/replacement/ pos points
to the end of the just replaced text.

$ cat MyScript
#!/bin/perl -w
local $\;
local $_ = <STDIN>;
while ( /(?=(["']))/xg ) {
$C = $1;
$Type = $C eq '"' ? 'DQ' : 'SQ';
s<\G($C.*?$C)>
<\\begin\{Yas$Type\}$1\\end\{Yas$Type\}>m;
}
print $_;
 
F

Florian Kaufmann

the modifier for the s<><> operator in my example should of course be
s not m, in order for . to match also newlines
 
C

comp.llang.perl.moderated

Simplified to the basics I have the following problem: I want to
replace occurrences of double or single quoted strings in a text file.
The following shows what I want to get.

$ cat MyFile
foo "D'Quote" bar 'S"Qu
ote'

$ MyScript < MyFile
foo \begin{YasDQ}"D'Quote"\end{YasDQ} bar \begin{YasSQ}'S"Qu
ote'\end{YasSQ}

As you can see, the quotes have now new strings (in this example latex
commands) around them. Also note that a single quote within a double
quote is not a meta character anymore, and vice versa. Newlines must
not be treated special.

That's what I tried: It basically searches the next quote. From the
found position onwards it replaces the text up to the next matching
quote. It doesn't work however. I assume mainly because s/// does not
change pos($_) as m// does. I think I just need to know how to
accomplish that after something like s/regex/replacement/ pos points
to the end of the just replaced text.

$ cat MyScript
#!/bin/perl -w
local $\;
local $_ = <STDIN>;
while ( /(?=(["']))/xg ) {
$C = $1;
$Type = $C eq '"' ? 'DQ' : 'SQ';
s<\G($C.*?$C)>
<\\begin\{Yas$Type\}$1\\end\{Yas$Type\}>m;}

print $_;

Here's a different approach via composition:

my @SQ = ( qw/ \begin{YasSQ} \end{YasSQ} / );
my @DQ = ( qw/ \begin{YasDQ} \end{YasDQ} / );
my $str = "";
while( m/\G(.*?)
(["'])
(.*?)
\2
/sxg ) {

$str .= ( $2 eq "'" ? qq[$1$SQ[0]$2$3$2$SQ[1]]
: qq[$1$DQ[0]$2$3$2$DQ[1]] );
}
 
T

Tad J McClellan

Florian Kaufmann said:
Simplified to the basics I have the following problem: I want to
replace occurrences of double or single quoted strings in a text file.
The following shows what I want to get.

$ cat MyFile
foo "D'Quote" bar 'S"Qu
ote'

$ MyScript < MyFile
foo \begin{YasDQ}"D'Quote"\end{YasDQ} bar \begin{YasSQ}'S"Qu
ote'\end{YasSQ}


my %q = ( q/"/ => 'YasDQ',
q/'/ => 'YasSQ'
);

s/(['"])(.*?)\1/\\begin{$q{$1}}$1$2$1\\end{$q{$1}}/gs;
 
C

comp.llang.perl.moderated

Simplified to the basics I have the following problem: I want to
replace occurrences of double or single quoted strings in a text file.
The following shows what I want to get.
$ cat MyFile
foo "D'Quote" bar 'S"Qu
ote'
$ MyScript < MyFile
foo \begin{YasDQ}"D'Quote"\end{YasDQ} bar \begin{YasSQ}'S"Qu
ote'\end{YasSQ}

...

Here's a different approach via composition:

my @SQ = ( qw/ \begin{YasSQ} \end{YasSQ} / );
my @DQ = ( qw/ \begin{YasDQ} \end{YasDQ} / );
my $str = "";
while( m/\G(.*?)
(["'])
(.*?)
\2
/sxg ) {

$str .= ( $2 eq "'" ? qq[$1$SQ[0]$2$3$2$SQ[1]]
: qq[$1$DQ[0]$2$3$2$DQ[1]] );

}

This 'solution' has problems... won't handle trailing characters after
the final quote-pair
for instance. See Tad's solution.
 

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,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top