Abigail, my apologies, I did mean string, instead of expr. I apparently tried to correct this ambiguity by stating "Subexpr should be a ... string," failing to realize my terminology error. My bad. I think the return value of &replace_mid('aaa', 'a+', 'B') should be 'B', but that's just my humble opinion. How would one handle true expressions, instead of mere strings? Yanick, your sub doesn't care much for a string containing newlines, merely a trifle, but I thought I'd mention it. Also, why did you predecrement and +1 instead of just postdecrimenting? Jacob. > -----Original Message----- > From: abigail@foad.org [mailto:abigail@foad.org] > Sent: Thursday, March 08, 2001 4:45 PM > To: Jacob Carpenter > Cc: 'fwp@technofile.org' > Subject: Re: [FWP] subexpr nearest the 'middle' of expr > > > All your examples have subexpressions without regex meta characters, > so it's clear what to do. > > But what if I call replace_mid ('aaaaa', 'a+', 'B')? What is > the intended > return value? 'B'? 'aaBaa'? 'aBa'? 'aB'? 'Ba'? All equally good? > > Or do you mean string where you write expr? (The first argument of > replace_mid being a regex doesn't make much sense). > > > If the arguments are just strings, there's a simple algorithm. > Calculate where the substring should start if it's to be put exactly > in the middle, then from that position, use index() and rindex() to > find the "next" and "previous" match. Compare which one is closest to > the middle, then substitute: > > sub replace_mid { > my ($string, $substring, $replacement) = @_; > > my $N = length $string; > my $M = length $substring; > > return if $N < $M; # No solution possible. > > # Find the mid. > my $mid = ($N - $M) / 2; > > my $index1 = index $string, $substring, $mid; > my $index2 = rindex $string, $substring, $mid; > > return if $index1 == -1 && $index2 == -1; # No match. > > # Two cases of only a match when going in one direction. > if ($index1 == -1) { > substr $string, $index2, $M, $replacement; > return $string; > } > if ($index2 == -1) { > substr $string, $index1, $M, $replacement; > return $string; > } > > # Now we have two potential candidates. > if ($N - ($index2 + $M) <= $index1) { > # rindex wins. > substr $string, $index2, $M, $replacement; > return $string; > } > else { > # index wins. > substr $string, $index1, $M, $replacement; > return $string; > } > } > > > It's too late though to check it for off-by-one errors though, but a > few tests seemed to give the right answers. > > > > Abigail > ==== Want to unsubscribe from Fun With Perl? Well, if you insist... ==== Send email to <fwp-request@technofile.org> with message _body_ ==== unsubscribe