In a string I want to find all matches of a regex in a string, save the matches and replace the matches. Is there a slick way to do that?
Example:
my $re = qr{\wat};
my $text = "a cat a hat the bat some fat for a rat";
... (substitute $re -> 'xxx' saving matches in @matches)
# $text -> 'a xxx a xxx the xxx some xxx for a xxx'
# @matches -> qw(cat hat bat fat rat)
I've tried: @matches = ($text =~ s{($re)}{xxx}g)
but it gives me a count.
Do I have to add some executable code onto the end of pattern $re
?
Update: Here is a method which uses the code execution extended pattern (?{... })
:
use re 'eval'; # perl complained otherwise
my $re = qr{\wat};
my $text = "a cat a hat the bat some fat for a rat";
my @x;
$text =~ s{ ($re)(?{ push(@x, $1)}) }{xxx}gx;
say "text = $text";
say Dumper(\@x); use Data::Dumper;
This is similar to the approach in your Update, but a bit easier to read:
$text =~ s/($re)/push @x, $1; 'xxx'/ge;
Or this way (probably slower):
push @x, $1 while $text =~ s/($re)/xxx/;
But, really, is there anything wrong with unslick ?
my @x = $text =~ /($re)/g;
$text =~ s/($re)/xxx/g;
If by "slick" you mean "employs uncommonly-used language features" or "will make other programmers scratch their heads," then maybe this is the solution for you:
my ($temp, @matches);
push @matches, \substr($text, $-[0], $+[0] - $-[0]) while $text =~ /\wat/g;
$temp = $$_, $$_ = 'xxx', $_ = $temp for reverse @matches;
my @x = map { $str =~ s/$_/xxx/; $_ } $str =~ /($re)/g;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.