[LA.pm] String handling like C array

Benjamin J. Tilly ben_tilly at operamail.com
Mon Feb 6 23:20:48 PST 2006


Use the right tool for the job.

unpack is not the right tool for your swap.  Regular expressions are.  Here is your swap in native Perl:

  $string =~ s/(x|y)/$1 eq "x" ? "y" : "x"/eg;

This is not just less code than you had in C, the idea is also far more flexible.  For instance suppose we want to swap Bill and Charles:

  $string =~ s/(Bill|Charles)/$1 eq "Bill" ? "Charles" : "Bill"/eg;

Try writing that in C!  (Be sure and be careful to take care of buffer overflows!)

Or suppose that we want to swap x and y only when they are not part of a word:

  $string =~ s/\b(x|y)\b/$1 eq "x" ? "y" : "x"/eg;

And the technique can be generalized to handle more complex sets of translations.  Here is the generalization with the original example:

  my %trans = (
    "x" => "y",
    "y" => "x",
  );
  my $pat = join "|", map quotemeta($_), keys %trans;
  $string =~ s/($pat)/$trans{$1}/g;

Now the translation to do has been extracted and placed in a hash.  Which means that your code stays the same while the translation gets more complex.  For instance you could do something like this:

  my %trans = (
    "x" => "y",
    "y" => "z",
    "z" => "x",
  );
  my $pat = join "|", map quotemeta($_), keys %trans;
  $string =~ s/($pat)/$trans{$1}/g;

or you could load the translation from a file somewhere, etc.

The long and short of it is that while you can pretend that Perl is as bad as C for manipulating text, it is a *lot* better when you learn to use Perl as it was designed to be used.

Cheers,
Ben

PS If pack/unpack is wrong for this job, what is it good for?  The answer is producing or parsing fixed width data structures.

> ----- Original Message -----
> From: "Robin Rowe" <rower at movieeditor.com>
> To: Losangeles-pm at pm.org
> Subject: Re: [LA.pm] String handling like C array
> Date: Sat, 04 Feb 2006 01:15:23 -0800
> 
> 
> Jeff,
> 
> Interesting. I've never used unpack. Can you show me what that could
> look like if used in the idiom of my SwapXY example?
> 
> Robin
> 
> Jeff wrote:
> > The "array level" needs better definition.
> >
> > Depends on what you want exactly,  in general, I guess unpack()
> > also traverse the string nicely.
> >
> > Not sure if this answers your question.
> >
> > - J
> > On Feb 3, 2006, at 2:31 PM, Robin Rowe wrote:
> >
> >> I often walk through strings as arrays in C, an idiom something like
> >> this contrived example:
> >>
> >> void SwapXY(char* string)
> >> {  char* ptr=string;
> >>     while(*ptr)
> >>     {  const char c=*ptr;
> >>        if('x'==c)
> >>        {  *ptr='y';
> >>        }
> >>        else if('y'==c)
> >>        {  *ptr='x';
> >>        }
> >>        ptr++;
> >>     }
> >> }
> >>
> >> In Perl would I walk the string using substr and length or is there a
> >> better way to do array-level string manipulation?
> >>
> >> Robin
> >> _______________________________________________
> >> Losangeles-pm mailing list
> >> Losangeles-pm at pm.org
> >> http://mail.pm.org/mailman/listinfo/losangeles-pm
> >
> >
> >
> >
> _______________________________________________
> Losangeles-pm mailing list
> Losangeles-pm at pm.org
> http://mail.pm.org/mailman/listinfo/losangeles-pm

>



More information about the Losangeles-pm mailing list