As an interpreted language, Perl has features not normally found in compiled languages. We will focus on two of these features:
s/[0-9]+/X/
will replace the leftmost integer with "X".
However, complex expressions may appear in the second position
as well, with the e
option of the substitute function.
For example, the following code
s/([0-9]+)/"X" x length($1)/ewill replace
"abc123def"
with "abcXXXdef"
.
Suppose that you have a lot of code that is indented on multiples
of eight columns with tabs ("\t"
),
and you would prefer indentation on multiples of four columns.
The retab
program provides this service:
# Usage: retab < infile > outfile $indent = 4; while (<STDIN>) { s#^(\t+)#' ' x (length($1) * 8)#e; s#^( *)#' ' x (length($1) * $indent / 8)#e; s#^(( {8})*)#"\t" x (length($1) / 8)#e; print; }
e
option of the substitute function
allows evaluation on the fly in string substitution.
The eval
function provides a more general
form of expression evaluation.
Any string can be evaluated as a Perl program.
The string can be read from a file or generated on the fly.
Consider the following "hello world" program:
$program = 'print "Hello world\n";'; eval $program;The
rename
program uses eval
to solve a common programmer's problem.
Suppose that you have a large number of files
that you wish to rename in a uniform way.
For example, you wish to change the .c
suffix
to .cpp
.
The rename
program can do this and
many other renaming tasks, in just a few lines of Perl:
# Usage: rename perlExpression [files] # extract perlExpression from @ARGV[0] ($op = shift) || die "Usage: rename perlExpression [files]\n"; for (@ARGV) { $oldName = $_; eval $op; die $@ if $@; rename($oldName,$_) unless $oldName eq $_; }
## use an associative array named %age $age{"jane"} = 26; $age{"bill"} = "21"; $age{"fido"} = 3; print $age{"bill"}, "\n"; $age{"fido"} += 1;As with ordinary arrays, the prefix becomes
$
when accessing an element (a scalar value).keys()
function returns a list of all the keys.
E.g.
@K = keys(%age); foreach (@K) { print "Age of ", $_, " is ", $age{$_}, "\n"; }
value()
function returns a list of all the values.
E.g.
@V = values(%age); foreach (@V) { print "Age: ", $_, "\n"; }
each()
function returns a key-value pair,
one at a time. For example:
while( ($k, $v) = each(%age) ) { print "Age of ", $k, " is ", $v, "\n"; }
defined()
function can be used to determine whether
an associative array contains a given key. For example:
if (defined($age{$k})) { print "$k is present\n"; }
@ageArray = %age; ## ageArray[0] = "jane", ageArray[1] = 26 ## ageArray[2] = "bill", ageArray[3] = 21 ## ageArray[4] = "fido", ageArray[5] = 4 %colour = ("house", "white", "sky", "blue", "grass", "green"); ## colour{"house"} equals "white", etc.
delete()
function. For example:
delete $colour{"house"};removes the
"house"-"white"
pair from the
%colour
array.for( $i = 0; $i < 10; $i++ ) { for( $j = 0; $j < 10; $j++ ) { $Table{$i,$j} = $i * $j; } }builds a multiplication table named
%Table
.
In actual fact, an element $Table{4,3}
is implemented as a key-value pair where the key is
the string "4;3"
.
#!/public/bin/perl while(is run with the following input:) { chop; foreach (split(/ /)) { if (defined($aa{$_})) { $aa{$_}++; } else { $aa{$_} = 1; } } } foreach (sort(keys(%aa))) { print "$_: $aa{$_}\n"; }
Tree Ladle Picks (from "The Anguish Languish") Once pawn term dare lift tree ladle picks. Divorced ladle pick enter sickened ladle pick wore lacy, fawn-laughing gauze. Butter thread ladle pick ...
#!/public/bin/perl while() { chop; foreach (split(/\W+/)) { tr/A-Z/a-z/; if (defined($aa{$_})) { $aa{$_}++; } else { $aa{$_} = 1; } } } foreach (sort(keys(%aa))) { print "$_: $aa{$_}\n"; }