On Sep 17, Jason Tiller said:

>Assuming this is the way I want to go, here's what I've cooked up so
>far:

It's pretty good.  The only change I would make is to structure it in a
slightly more idiomatic fashion:

  my %paths;
  $paths{$_}++ for split /:/, $ENV{PATH};
  $ENV{PATH} = join ':', keys %paths;

>This works, but it feels really clunky.  In my exploration of perl
>RE's, I can "sense" that there might be a RE solution to this problem
>without having to go to the hassle of creating a bunch of arrays, a
>hash, and then looping through the entries.

Well, regexes are A way, but they're not necessarily the best
approach.  You'll end up having to do a lot of textual comparisons
(blegh) and the like.

  $ENV{PATH} =~ s{
    (?<! [^:] )  # make sure there's not a non-: behind us
    ([^:]+) :    # match the path to \1, and match a :
    (?=          # if it's followed by...
      (?: [^:]* : )*  # any other paths
      \1              # and then itself
      (?! [^:] )      # and is NOT followed by a non-:
    )
  }{}gx;         # remove it (and the colon that came after it)

The look-behind and look-ahead have double-negatives in them.  Let me
explain.  We want to match strings of non-:'s.  These denote paths.  But
we don't want to match the "oobar" of "foobar" in "abc:foobar:this:oobar"
because that would make a false positive.

So we create our own colon-boundary assertion by saying "be sure we are
NOT preceded by a non-colon."  That means we're either preceded by a colon
or the beginning of the string.  It could have been written as:

  (?: ^ | (?<= : ) )

The same logic is used for (?! [^:] ).  It could have been written as

  (?: $ | (?= : ) )

-- 
Jeff "japhy" Pinyan      [EMAIL PROTECTED]      http://www.pobox.com/~japhy/
RPI Acacia brother #734   http://www.perlmonks.org/   http://www.cpan.org/
** Look for "Regular Expressions in Perl" published by Manning, in 2002 **


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to