s/// does not affect pos?

s/// does not affect pos?

am 11.01.2008 13:13:38 von 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 $_ = ;
while ( /(?=(["']))/xg ) {
$C = $1;
$Type = $C eq '"' ? 'DQ' : 'SQ';
s<\G($C.*?$C)>
<\\begin\{Yas$Type\}$1\\end\{Yas$Type\}>m;
}
print $_;

Re: s/// does not affect pos?

am 11.01.2008 13:26:01 von 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

Re: s/// does not affect pos?

am 11.01.2008 19:15:04 von Charles DeRykus

On Jan 11, 4:13 am, Florian Kaufmann wrote:
> 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 $_ = ;
> 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]] );
}

--
Charles DeRykus

Re: s/// does not affect pos?

am 11.01.2008 19:40:06 von Jim Gibson

In article
<3b415432-aca2-4fb0-9a30-8dd5e59f67b3@h11g2000prf.googlegroups.com>,
Florian Kaufmann wrote:

> 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 $\;

ITYM: local $/;

> local $_ = ;
> while ( /(?=(["']))/xg ) {
> $C = $1;
> $Type = $C eq '"' ? 'DQ' : 'SQ';
> s<\G($C.*?$C)>
> <\\begin\{Yas$Type\}$1\\end\{Yas$Type\}>m;
> }
> print $_;
>

That program goes into an infinite loop for me. Is that what you mean
by "It doesn't work"?

You are modifying the string and expecting to start searching the
string where you last left off. That can't work.

I would use regular expression m//, index, and substr to find and
modify your string iteratively, building up a modified string in a
separate variable instead of trying to do it in place. Here is a method
using the $` variable, which might slow your program down somewhat, but
perhaps not by a significant amount:

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

my $text = do { local $/; };
my $newtext;
while( $text =~ m{ (["']) }x ) {
my $mark = $1;
$newtext .= $`;
my $tag = ( $mark eq q(") ? 'DQ' : 'SQ' );
$text = substr($text,length($`));
my $end = index($text,$mark,1);
if( $end >= 0 ) {
$newtext .= "\\begin{Yas$tag}" . substr($text,0,$end+1) .
"\\end{Yas$tag}";
$text = substr($text,$end+1);
}
}
$newtext .= $text;
print $newtext;
__DATA__
foo "D'Quote" bar 'S"Qu
ote'

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com

Re: s/// does not affect pos?

am 12.01.2008 03:00:39 von Tad J McClellan

Florian Kaufmann wrote:
> 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;


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"

Re: s/// does not affect pos?

am 12.01.2008 16:09:38 von Charles DeRykus

On Jan 11, 10:15 am, "comp.llang.perl.moderated" sam-01.ca.boeing.com> wrote:
> On Jan 11, 4:13 am, Florian Kaufmann wrote:
>
>
>
> > 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.

--
Charles DeRykus