regex - Substitute only in the matched part of a Perl pattern -
how can substitute in matched pattern , put in same variable using perl?
for example:
my $str = "a.b.aa pat1 bb hgf aa pat1 bb jkl cc pat1 don't change pat1";
i want match pat1
between aa
, bb
, replace original string pat2. however, don't want replace pat1
anywhere else in same string
expected output string:
a.b.aa pat2 bb hgf aa pat2 bb jkl cc pat1 don't change pat1
i sure there should way it; please advise.
original string:
my $org_str = 'a.b.c.\\valid.a .\\valid.a.b.c .\\valid.x.y.z .p.q.r.s';
expected string:
my $exp_op = 'a.b.c.\\valid?a .\\valid?a?b?c .\\valid?x?y?z .p.q.r.s';
substitute character .
?
if between backslash \
, whitespace .
not simple 1 single regexp, used divide , conquer compute result. small recursive function replacing single '.' per group of ('\' ' ')
the iteration ends when there nothing replace
sub replace { ($input) = @_; $result = $input; $result =~ s/(\\\s*?)\.(.*? )/$1?$2/g; return $result if $result eq $input; return replace($result); }
the function test cases
use strict; $org_str= 'a.b.c.\\\\valid.a .\\\\valid.a.b.c .\\\\valid.x.y.z .p.q.r.s'; $exp_op ='a.b.c.\\\\valid?a .\\\\valid?a?b?c .\\\\valid?x?y?z .p.q.r.s'; sub replace { ($input) = @_; $result = $input; $result =~ s/(\\\s*?)\.(.*? )/$1?$2/g; return $result if $result eq $input; return replace($result); } $check; $result; $expected; $check = 'abcd'; $expected = $check; $result = replace($check); assert($result eq $expected, "'$check' gives '$expected'"); $check = 'ab\xxx. cd'; $expected = 'ab\xxx? cd'; $result = replace($check); assert($result eq $expected, "'$check' gives '$expected'"); $check = 'ab\x.x.x. cd'; $expected = 'ab\x?x?x? cd'; $result = replace($check); assert($result eq $expected, "'$check' gives '$expected'"); $check = 'ab\x.x.x. cd\y.y.y.'; $expected = 'ab\x?x?x? cd\y.y.y.'; $result = replace($check); assert($result eq $expected, "'$check' gives '$expected'"); $check = 'ab\x.x.x. cd\xxx.xxx..xxx...x \y.y.y.'; $expected = 'ab\x?x?x? cd\xxx?xxx??xxx???x \y.y.y.'; $result = replace($check); assert($result eq $expected, "'$check' gives '$expected'"); $check = '. ..\.. ...\.. ...\.. ...\..'; $expected = '. ..\?? ...\?? ...\?? ...\..'; $result = replace($check); assert($result eq $expected, "'$check' gives '$expected'"); $check = $org_str; $expected = $exp_op; $result = replace($check); assert($result eq $expected, "'$check' gives '$expected'"); sub assert { ($cond, $mesg) = @_; print "checking $mesg ... "; die "\nfail: $mesg" unless $cond; print "ok\n"; }
the result
checking 'abcd' gives 'abcd' ... ok checking 'ab\xxx. cd' gives 'ab\xxx? cd' ... ok checking 'ab\x.x.x. cd' gives 'ab\x?x?x? cd' ... ok checking 'ab\x.x.x. cd\y.y.y.' gives 'ab\x?x?x? cd\y.y.y.' ... ok checking 'ab\x.x.x. cd\xxx.xxx..xxx...x \y.y.y.' gives 'ab\x?x?x? cd\xxx?xxx??xxx???x \y.y.y.' ... ok checking '. ..\.. ...\.. ...\.. ...\..' gives '. ..\?? ...\?? ...\?? ...\..' ... ok checking 'a.b.c.\\valid.a .\\valid.a.b.c .\\valid.x.y.z .p.q.r.s' gives 'a.b.c.\\valid?a .\\valid?a?b?c .\\valid?x?y?z .p.q.r.s' ... ok
Comments
Post a Comment