Hi, Mark, :)

On Wed, 11 Dec 2002 [EMAIL PROTECTED] wrote:

> I have a list of names, separated by the '/' character in a
> variable, $list, and a name in the variable $name.  If the name
> appears in the list, I want to remove it and clean up $list.  It
> takes me 4 calls to s///, and it looks clunky.  I have a feeling
> that someone out there on this list will know a cleaner way to do
> it.

> $list =~ s|$name||; # remove $name from the list if it's in the list

> $list =~ s|//|/|; # if $name was in the middle of the list, it would
>                   # have left behind two /s, remove one
> $list =~ s|^/||; # if $name was at the front of the list, remove the
>                  # leading /
> $list =~ s|/$||; # if $name was at the end of the list, remove the
>                  # trailing /

How about this:

use re 'eval'; # The (?{$num_slashes++}) construct requires this pragma.

$data =~ s{ (?:^|/)
               (?(?<=/) (?{$num_slashes++}))
               $name
               (?(?=/)  (?{$num_slashes++}))
            (?:/|$)
          }
          {'/' if $num_slashes == 2}ex;

Basically, match $name and all surrounding /'s; if there were two
slashes in the match, then stick the joining slash in as the
replacement.  That's it.

The main difference between this and Tanton's final result:

$data =~ s!(/)?\b$name\b(/)?!$2 ? ($1||'') : ($2||'')!e

Is that mine has no captures and no quaintifiers.  With all of my
evaluation, though, I have no idea which one runs faster.

BTW, I think Tanton's RE could be written as:

$data =~ s!(/)?\b$name\b(/)?!$2 ? ($1||'') : ''!e;

or

$data =~ s! (/)? \b$name\b (/)? ! $1||'' if defined($2) !ex;

With no ill effects.  (I find the trinary operator somewhat confusing
in a situation where you only want the 'if' portion and not the 'else'
portion.

Fun, fun!

---Jason


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

Reply via email to