Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using qr// with substitution and group-interpolation in the substitution part

9 views
Skip to first unread message

Josef Wolf

unread,
Oct 25, 2023, 1:45:07 PM10/25/23
to begi...@perl.org
Hallo all,

maybe this is not exactly a beginner question, but I could not find an
appropriate mailing list (all other lists seem to be developer realted).


Basically, I want to do the same as


$data =~ s/^foo (whatever) bar$/bar $1 baz/mg;


but with a different interface (because it has to be embedded into a bigger
project), So I have come with this;


sub substitute_lines {
my ($contents, $regex, $subst) = @_;
$contents =~ s/$regex/$subst/mg;
return $contents;
}
}

&substitute_lines ($data, qr/^foo (whatever) bar$/mg, 'bar $1 baz');


Which (mostly) works as expected. Unfortunately, this won't interpolate the
matched group $1.

Experiments which also do not work:


&substitute_lines ($data, qr/^foo (whatever) bar$/mg, "bar $1 baz");
# obviously, $1 is interpolated _before_ re-match is done


&substitute_lines ($data, qr/^foo (whatever) bar$/mge, '"bar $1 baz"');
# /e modifier not accepted

Any hints?

--
Josef Wolf
j...@raven.inka.de

gordonfish

unread,
Nov 21, 2023, 11:15:08 PM11/21/23
to begi...@perl.org
On 10/25/23 10:32, Josef Wolf wrote:

[...]

> Basically, I want to do the same as
>
>
> $data =~ s/^foo (whatever) bar$/bar $1 baz/mg;
>
>
> but with a different interface (because it has to be embedded into a bigger
> project), So I have come with this;
>
>
> sub substitute_lines {
> my ($contents, $regex, $subst) = @_;
> $contents =~ s/$regex/$subst/mg;
> return $contents;
> }
> }
>
> &substitute_lines ($data, qr/^foo (whatever) bar$/mg, 'bar $1 baz');
>
>
> Which (mostly) works as expected. Unfortunately, this won't interpolate the
> matched group $1.
[...]

You could so something like:

use feature qw(signatures);

sub substitute_lines($contents, $regex, $subst) {
$contents =~ s/$regex/$subst->()/emgr;
}

...

substitute_lines
$data,
qr/^foo (whatever) bar$/,
sub { "bar $1 baz" };


This will pass an anonymous sub routine which will be called from s///
replacement side thanks to the /e modifier that allows code to be
executed there.

Also of some note is that the /r modifier is used so that s/// returns
the resulting string instead of modifying $contents, and being the last
statement, said resulting string is the return value.

--
gordonfish


gordonfish

unread,
Nov 21, 2023, 11:45:08 PM11/21/23
to begi...@perl.org
On 11/21/23 20:08, gordonfish wrote:
> On 10/25/23 10:32, Josef Wolf wrote:
>
> [...]
>
>> Basically, I want to do the same as
>>
>>
>>    $data =~ s/^foo (whatever) bar$/bar $1 baz/mg;
>>
>>
>> but with a different interface (because it has to be embedded into a
>> bigger
>> project), So I have come with this;
>>
>>
>>    sub substitute_lines {
>>        my ($contents, $regex, $subst) = @_;
>>            $contents =~ s/$regex/$subst/mg;
>>            return $contents;
>>        }
>>    }
>>
>>    &substitute_lines ($data, qr/^foo (whatever) bar$/mg, 'bar $1 baz');
>>
>>
>> Which (mostly) works as expected. Unfortunately, this won't
>> interpolate the
>> matched group $1.
> [...]


---Reposting due to code indents being eaten---

gordonfish

unread,
Nov 22, 2023, 7:45:07 PM11/22/23
to begi...@perl.org
On 10/25/23 10:32, Josef Wolf wrote:
[...]
> Basically, I want to do the same as
>
>
> $data =~ s/^foo (whatever) bar$/bar $1 baz/mg;
>
>
> but with a different interface (because it has to be embedded into a bigger
> project), So I have come with this;
>
>
> sub substitute_lines {
> my ($contents, $regex, $subst) = @_;
> $contents =~ s/$regex/$subst/mg;
> return $contents;
> }
> }
>
> &substitute_lines ($data, qr/^foo (whatever) bar$/mg, 'bar $1 baz');
>
>
> Which (mostly) works as expected. Unfortunately, this won't interpolate the
> matched group $1.
[...]
0 new messages