[San-Diego-pm] Recompiling global substitution RE?

Reuben Settergren ruberad at gmail.com
Sat Mar 20 16:13:23 PDT 2010


Hey gang,

I think I have a solution now, with the help of Mark Johnson. I should give
you more clarification that my actual problem (still simplified) looks more
like:

DIST - Distance
    DISTANCE:   12.3456 ft    4.5678 m
    STD DEV:     3.4567 ft    1.2345 m

AREA - Area
    AREA:      2345.6789 ft^2   345.6789 m^2
    PERIMETER:  234.5678 ft      89.0123 m
    STD DEV:      3.4567 ft       1.2345 m

DIST - Distance
    DISTANCE:   12.3456 ft   4.5678 m
    STD DEV:     3.4567 ft    1.2345 m

DIST - Distance
    DISTANCE:    8.9012 ft    3.0123 m
    STD DEV:     1.2345 ft    0.4567 m
...etc


So in any one situation, I will have a set of numbers/colors for a
particular combination of function/metric/unit (i.e. DIST/'STD DEV'/ft:
(3.4567,3.4567,1.2345),(red,green,yellow)). So I have to avoid the other
functions (e.g. AREA) that might have the same numbers. Note my first
attempt
for $i (0..$#nums) {
   $str =~ s{($function.*$metric.*)(?<!>)($vals[$i]\s+$unit)}
            {$1<span color="$cols[$i]">$2</span>}
}
didn't work because in the second time through the loop, $1 matched from the
very beginning, and $2 was the 3.4567 in the AREA function.

But with Mark Johnson's idea, I can chomp through my whole
file-in-one-string bit-by-bit, something like:

$head = '';
$tail = $s;
for my $i ( 0 .. $#nums ) {
    $tail =~ s/(.*?$function.*?$metric.*?)($nums[$i]\s+$unit)(.*)/$3/;
    $head .= "$1<span color="$cols[$i]">$2</span>";
}
$s = "$head$tail";

If there isn't already a name for this cool kind of trick, there should
be: train cars? chewandswallow? sausage grinder? Any other ideas?

r



On Sat, Mar 20, 2010 at 8:41 AM, Gautam Dey <gautam.dey77 at gmail.com> wrote:

> Reuben,
>
>   Trying to figure out how you are determining when to do the substitution?
>
>
>
> 2010/3/19 Reuben Settergren <ruberad at gmail.com>:
> <snip>
> >
> > #! /bin/perl
> > $s = "1 2 3 1 2 3 1 2 3";          # what I have
> > $t = "sg1s 2 3 sr1s 2 3 1 sy2s 3"; # what I want
>
> How do you know that there are two elements after the first 1 to generate
> the "sg1s 2 3" and that there are three elements after the 1 to generate
> the
> "sr1s 2 3 1" and that there is only 1 element after the 2 to generate the
> "sy2s 3". The transformation seem a bit more complicated then what can
> be done with a simple regular expresion .
>
> s/something/text/g replaces all occurrences of something with text.
> So, you regular expression seems to be replacing all occurrences of 1
> with the appropriate  evaluated code.  But, I'm not sure as
> 's!($nums[$i++])!s$cols[$j++]$1s!g'  is a bit on the unusual side of
> things.
>
> Gautam.
>
> > @nums = qw(1 1 2);
> > @cols = qw(g r y);
> > $i=$j=0;
> > $s =~ s!($nums[$i++])!s$cols[$j++]$1s!g;
> > print "Want: '$t'\n";
> > print "Got:  '$s'\n";
> > print "i is now $i\n";
> > print "j is now $j\n";
> >
> > The output of this program is unfortunately:
> >
> > Want: 'sg1s 2 3 sr1s 2 3 1 sy2s 3'
> > Got:  'sg1s 2 3 sr1s 2 3 sy1s 2 3'
> > i is now 1
> > j is now 3
> >
> > Perl ended up incorrectly coloring the third ‘1′ yellow, instead of the
> > third ‘2′, because in the substitution regular expression, the left
> > (matching) side was evaluated/compiled only once, while the right
> > (replacement) side was evaluated/interpolated three times (as desired).
> >
> > I know that there are ways to force the left side of the RE to compile
> only
> > once (/o modifier, qr// operator), and there are ways to force eval in
> the
> > right side (/e and /ee modifiers — although in this case, standard
> > interpolation was sufficient), but is there any way I can force
> > the left side to compile multiple times? (Even within the same /g
> > substitution?) I tried a few constructs using the \G (start matching from
> > previous position) zero-width assertion, but only managed to get myself
> into
> > infinite loops.
> >
> > I'd appreciate any help anyone can offer -- including "What an idiot, the
> > RIGHT way to do that is completely different! (And here it is...)"
> >
> > thx for thinking for me!
> >
> > r
> >
> >
> >
> > _______________________________________________
> > San-Diego-pm mailing list
> > San-Diego-pm at pm.org
> > http://mail.pm.org/mailman/listinfo/san-diego-pm
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/san-diego-pm/attachments/20100320/a2363761/attachment.html>


More information about the San-Diego-pm mailing list