how would you do this?

j proctor jproctor at oit.umass.edu
Mon Oct 4 15:43:03 CDT 1999


On the Jax.PM jacksonville-pm-list;
j proctor <jproctor at oit.umass.edu> wrote -




> I want to translate a string captured from a web form into readable
> output. It seems that I should to use the built in functions hex() and
> chr(), right?

Nope.  Keep reading...


> Now if $_ contains the string "You%20guys%20rule%21"
> can I do something like this:
> 
> $name=~ s/$_/chr(hex($_))/ge ;

Yes.  But not exactly like that.

A possible problem with your code, Nate, is that s/// may not actually be
working on $_ and then assigning the results to $name.  I've never
actually tried it that way, so it looked a little suspicious.  You may
need to explicitly $name = $_ before the s///, or $name out of the s///
and then put $_ into $name later if you need that value after $_ is
reassigned to something else.

I've also never tried using chr(hex()), although I'm sure you'll need
the match half of the s/// to actually say which parts to treat as a
hex-encoded character.  Try using:

s/%([0-9a-f]{2})/pack("H2", $1)/egi;

and see what you get.


Caveat:  This code still doesn't do quite what a web browser or server
would, since it would take input like

%25%50%49       # that's "%21" encoded, btw.

and boil down to "!" instead of stopping at "%21".


j


Explanation, for those that don't see their way through my dense little
RegEx that I swiped from somewhere else (long since forgotten):

Take whatever's in $_ and perform the following substitution:

  Find a pattern that starts with % and is followed by exactly two
  characters in the set [0123456789abcdefABCDEF].  The /i modifier 
  at the end is what makes it case-insensitive.  The parentheses 
  aren't actually matched; they allow us to remember which two hex
  digits we found so we can use them later.

  The /e modifier is what lets us put a function call as the
  replacement string instead of straight text.

    That function is pack, which takes a list of values (in this
    case, $1, which is whatever's inside the aforementioned parens)
    and tries to interpret that list according to a pattern ("H2"
    is the pack code for two hex digits).  Assuming pack can match 
    the data with the pattern, it returns a scalar string of byte(s) 
    that Perl can conveniently treat just like any other string.

  Finally, the /g says keep doing it until you don't find any more
  things that match the original pattern.






The Jacksonville Perl Monger's Group is operated by -
Bill -Sneex- Jones ( sneex at usa.net ),
to whom send all praises, complaints, or comments...




More information about the Jacksonville-pm mailing list