From: Willem on
Hello,

For a program I'm writing that does a few regex-based substitutions
in a large file, I would like to see exactly what substitutions are
being done. I.E. Which strings were matched, and what they were
replaced by.

Or, in code: if I do:

$content =~ s/<add key="(.*?).foobar.\d+" value="Foo=.*?;(.*?"/>)/
<add key="$1.foobar.10" value="Foo=20;$2/g;

I want to display stuff like:
Substitution: '<add key="one.foobar.12" value="Foo=15;Bar=3"/>'
=> '<add key="one.foobar.10" value="Foo=20;Bar=3"/>'
Substitution: '<add key="two.foobar.12" value="Foo=15;Bar=8"/>'
=> '<add key="two.foobar.10" value="Foo=20;Bar=8"/>'

I have already succeeded in doing this by making a loop around
while ($content =~ /.../g)

where I used the @- and @+ arrays to get at the matches, and then
manually fill in the $1 .. $x variables.
That's pretty complicated, however, and also the actual substitution is
pretty hairy too (I had to do another s/// with the strings I just created
and displayed).

Is there an easier way to get at what a substitution is doing ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
From: Marc Girod on
On Mar 24, 6:35 pm, Willem <wil...(a)turtle.stack.nl> wrote:

> Is there an easier way to get at what a substitution is doing ?

Run under the debugger, with an action to print the values before and
after?

Marc
From: sln on
On Wed, 24 Mar 2010 18:35:05 +0000 (UTC), Willem <willem(a)turtle.stack.nl> wrote:

>Hello,
>
>For a program I'm writing that does a few regex-based substitutions
>in a large file, I would like to see exactly what substitutions are
>being done. I.E. Which strings were matched, and what they were
>replaced by.
>
>Or, in code: if I do:
>
> $content =~ s/<add key="(.*?).foobar.\d+" value="Foo=.*?;(.*?"/>)/
> <add key="$1.foobar.10" value="Foo=20;$2/g;
>
>I want to display stuff like:
> Substitution: '<add key="one.foobar.12" value="Foo=15;Bar=3"/>'
> => '<add key="one.foobar.10" value="Foo=20;Bar=3"/>'
> Substitution: '<add key="two.foobar.12" value="Foo=15;Bar=8"/>'
> => '<add key="two.foobar.10" value="Foo=20;Bar=8"/>'
>
>I have already succeeded in doing this by making a loop around
> while ($content =~ /.../g)
>
>where I used the @- and @+ arrays to get at the matches, and then
>manually fill in the $1 .. $x variables.
>That's pretty complicated, however, and also the actual substitution is
>pretty hairy too (I had to do another s/// with the strings I just created
> and displayed).
>
>Is there an easier way to get at what a substitution is doing ?
>
>
>SaSW, Willem

Probably the literals '.' and '/' should be escaped.
I'm suprised it worked.

This is one way, probably more ways.
-sln
--------------

use strict;
use warnings;

my $tmp;
my $content = qq{
<add key="one.foobar.12" value="Foo=15;Bar=3"/>
<add key="two.foobar.12" value="Foo=15;Bar=8"/>
};

$content =~ s/(<add key=".*?\.foobar\.)(\d+)(" value="Foo=)(.*?)(;.*?"\/>)/
$tmp = $1.'10'.$3.'20'.$5;
print "Substitution: '$1$2$3$4$5'\n => '$tmp'\n";
$tmp/eg;

print $content;

__END__

From: Willem on
Marc Girod wrote:
) On Mar 24, 6:35?pm, Willem <wil...(a)turtle.stack.nl> wrote:
)
)> Is there an easier way to get at what a substitution is doing ?
)
) Run under the debugger, with an action to print the values before and
) after?

1 - I want just the bits that are substituted, although that
may very well be possible in the debugger ?
2 - This is for a user app, and I want the user to see the changes.

Especially #2 rules out using the debugger.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
From: Ben Morrow on

Quoth Willem <willem(a)turtle.stack.nl>:
>
> For a program I'm writing that does a few regex-based substitutions
> in a large file, I would like to see exactly what substitutions are
> being done. I.E. Which strings were matched, and what they were
> replaced by.
>
> Or, in code: if I do:
>
> $content =~ s/<add key="(.*?).foobar.\d+" value="Foo=.*?;(.*?"/>)/
> <add key="$1.foobar.10" value="Foo=20;$2/g;
>
> I want to display stuff like:
> Substitution: '<add key="one.foobar.12" value="Foo=15;Bar=3"/>'
> => '<add key="one.foobar.10" value="Foo=20;Bar=3"/>'
> Substitution: '<add key="two.foobar.12" value="Foo=15;Bar=8"/>'
> => '<add key="two.foobar.10" value="Foo=20;Bar=8"/>'
>
> I have already succeeded in doing this by making a loop around
> while ($content =~ /.../g)
>
> where I used the @- and @+ arrays to get at the matches, and then
> manually fill in the $1 .. $x variables.
> That's pretty complicated, however, and also the actual substitution is
> pretty hairy too (I had to do another s/// with the strings I just created
> and displayed).

It shouldn't need to be complicated.

while ($content =~ /foo(\d+)/g) {
my ($start, $end) = ($-[0], $+[0]);
# this qq// should contain exactly what you would have put
# in the RHS of the s///
my $after = qq/bar$1/;
my $before = substr $content, $start, $end, $after;
}

(untested) ought to work, though you may need

pos($content) = $start + length $after;

as well.

Ben