File forsojunk
is as follows (with many more lines not shown).
s/e\x27\x27\x27/é/g;
s/e\x27/é/g;
s/a\x5f/à/g;
junk.pl
is as follows.
#! /usr/bin/perl
use strict; use warnings;
while(<>) {
$_ =~ s/s\x2f([^\x2f\x5c]+)([^\x2f]*)\x2f([^\x2f]*).*/1=$1; 2=$2; 3=$3/ ;
print $1;
print $2;
print " -> ";
print $3;
print "\n";
}
which gives
> junk.pl forsojunk
e\x27\x27\x27 -> é
e\x27 -> é
a\x5f -> ò
but I do not want to print out the literal hex code such as \x27\x27\x27
. I want to print out what it looks like, the readable form. At the first line, $2
should print out as '''
and
the entire "message" in the first line should be
e''' -> é
How does one accomplish this?
You need to convert each 2-digit hexcode to a printable character.
pack
works, or using a loop with hex
to convert from a base-16 string to a number, and then chr
, printf
, etc to convert to the corresponding character:
#!/usr/bin/env perl
use strict;
use warnings;
use open qw/IO :locale :std/;
while(<>) {
# Note the cleaned up regular expression
if (my ($base, $rawaddons, $result) = m{s/([^/\\]+)([^/]*)/([^/]*)/}) {
my @addons = split/\\x/, $rawaddons; # Split up the hexcodes and remove the \\x parts
shift @addons; # Drop the first empty element
print $base;
# Any of the below ways work
print pack('(H2)*', @addons);
# printf '%c', hex for @addons;
# print map { chr hex } @addons;
print " -> $result\n";
}
}
Example:
$ perl junk.pl forsojunk
e''' -> é
e' -> é
a_ -> à