[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

RE: [FWP] subexpr nearest the 'middle' of expr



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