📄 ch5.htm
字号:
</PRE>
</BLOCKQUOTE>
<P>
OPERATION may be the operation to modify the array, or a series
of do statements, as in the following listing.
<BLOCKQUOTE>
<PRE>
do {
statement1;
statement2;
statement3;
{
</PRE>
</BLOCKQUOTE>
<P>
@array_name is the array having all its elements modified. If
you were an unscrupulous Web administrator, you might double the
entries to the array where your Web page hits are stored, like
so:
<BLOCKQUOTE>
<PRE>
grep($_ *= 2), @hits);
</PRE>
</BLOCKQUOTE>
<P>
where Web page hits are stored in @hits.
<H4>Operating on a Series of Integers</H4>
<P>
If you need to pass a series of integers through the same operation,
you can do this by using a foreach loop:
<BLOCKQUOTE>
<PRE>
foreach $temp(low..high) {
OPERATION;
}
</PRE>
</BLOCKQUOTE>
<P>
$temp is the scalar variable into which each integer is placed
for the operation; low and high are the range of the integers;
and OPERATION is the statement (or statements) that you need every
integer to go through. In this procedure, the command for will
work in place of foreach. A sample use of this procedure might
look like this:
<BLOCKQUOTE>
<PRE>
tfor $count(1..2Ø) {
print "$count\n";
}
</PRE>
</BLOCKQUOTE>
<P>
where a countdown from 1 to 20 will take place.
<H4>Processing All the Elements of an Array</H4>
<P>
This procedure is used to execute one or more commands on the
entire list of elements in an array. The basic format is:
<BLOCKQUOTE>
<PRE>
foreach (@array_name) {
statement1;
statement2;
}
</PRE>
</BLOCKQUOTE>
<P>
where @array_name has both statement1 and statement2 applied to
it. A possible use for this procedure might be as shown in the
following:
<BLOCKQUOTE>
<PRE>
foreach (@accounts) {
last if $_ eq 'Ø';
print "Account balance is $_\n";
print "Account is empty.\n" if /Ø/;
}
</PRE>
</BLOCKQUOTE>
<P>
where you check @accounts to output the balance of each, and if
it is a zero balance, the "Account is empty" string
is returned.
<H4>Removing Multiple Consecutives of the Same Character</H4>
<P>
If you need to remove multiple, consecutive occurrences of characters
in your script, you can use this procedure, which uses the "tr///"
function to transliterate each character of one string into the
corresponding character of another string, but with the "s"
option causing the "tr" function to push any consecutive
occurrences of a character into only one character. The absence
of a replacement string normally used with "tr" leaves
only the changed string.
<P>
To have the procedure check all the characters in a string, the
following script applies:
<BLOCKQUOTE>
<PRE>
while (<STDIN>) {
tr/\Ø-\377//s;
print;
}
</PRE>
</BLOCKQUOTE>
<P>
where the string being held in <STDIN> is processed and
all multiple, consecutive occurrences of a character are removed.
<H4> Counting Items in an Array</H4>
<P>
Arrays may be used to count the number of times a particular string
sequence occurs in a file. This procedure makes use of a simple
for loop with the following basic format
<BLOCKQUOTE>
<PRE>
for (@array_name) {
$count{$_}++;
}
for (sort keys %count) {
printf "%Xs %d\n", $_, $count{$_};
}
</PRE>
</BLOCKQUOTE>
<P>
The array being searched for the string count is @array_name;
each part of the string is placed into $_ and then counted; X
is the integer value of the number of columns to hold the tabulated
values; and $count is the number of times of string occurrence.
<P>
This procedure can be used to report on how many times users'
real names occur:
<BLOCKQUOTE>
<PRE>
@users = grep(s/\s.*\n?$//,'user');
for (@users) {
$count{$_}++;
}
for (sort keys $count) {
printf "%8s %d/n", $_, $count{$_};
}
</PRE>
</BLOCKQUOTE>
<P>
where @user holds the users' real names, and the results are printed
to eight columns of output.
<H2><A NAME="MiscellaneousProcedures"><FONT SIZE=5 COLOR=#FF0000>
Miscellaneous Procedures</FONT></A></H2>
<P>
These are the many procedures that don't easily fall into either
of the previous categories.
<H4>Renaming a File</H4>
<P>
Put simply, this procedure renames a file
<BLOCKQUOTE>
<PRE>
rename($previous,$current) ||
die " Unable to make file name change from $previous to $current: $!";
</PRE>
</BLOCKQUOTE>
<P>
$previous is the name of the file to be changed and $current is
the new name for the file. You can use this procedure to take
any ASCII files and make them useful to a browser by adding the
.html file extension. In action this script looks like the following:
<BLOCKQUOTE>
<PRE>
rename($html, "$html.html") ||
die " Unable to make file name change from $html to "$html.html": $!";
</PRE>
</BLOCKQUOTE>
<P>
where you take the file in $html and add the extension ".html."
<H4>Using Subroutines to Return Errors</H4>
<P>
You may need to have a subroutine return a pass/fail indication
when it returns a list. The way to do this is be sure to include
the pass/fail indicator as the first entry of the list. The basic
format of this procedure is as shown here:
<BLOCKQUOTE>
<PRE>
sub subroutine_name {
statement1;
statement2;
}
{
local(@return) = &subroutine_name(subroutine_parameters);
if (shift @return) {
success_statement;
} else {
fail_statement;
}
}
</PRE>
</BLOCKQUOTE>
<P>
The subroutine_name is the subroutine created to return a list;
statement1 and statement2 are where the values of a successful
or failed return are defined; @return is the local array where
subroutine_name and subroutine_parameters are stored; and the
if/else loop returns either the success_statement or the fail_statement.
<P>
If you wanted to have a list of a Web site page returned, and
also to be notified if this procedure has succeeded or failed,
then you might use this procedure:
<BLOCKQUOTE>
<PRE>
sub site_pages {
local(*directory);
opendir(directory, $_[Ø]) || return Ø
local(@pages) = sort grep(!/^\.\.?$/, readdir(directory));
closedir(directory);
return 1, @pages;
}
{
local(@return) = &pages($ENV{HOME}) || $ENV{LOGDIR});
if (shift @return) {
print "The HTML documents which make up this site are @return\n";
}
}
</PRE>
</BLOCKQUOTE>
<P>
where "directory" is the directory housing the HTML
documents you are listing.
<H4>Hiding Escaped Characters</H4>
<P>
There may be a time in your script when you'll need certain characters
shielded, or hidden, from a global operation being applied to
that area of the Perl script. If you want to hide the special
backslash characters because they might be viewed by Perl as regularly
occurring characters without special status, then use this format:
<BLOCKQUOTE>
<PRE>
s/\\(.)/"unmatch1".ord$1).("unmatch2")/e.g.;
operation(s);
s/unmatch1(d+)unmatch2/pack(C,$1)/e.g.;
</PRE>
</BLOCKQUOTE>
<P>
Here, the string being processed is assumed to already be in $_.
In order to hide the escaped characters you use "unmatch1"
and "unmatch2" as two characters not likely to be occurring
in the string being processed. Good examples of these are \376
and \377.
<P>
If you need to change overall occurrences of the string "guest"
with a new string "member," but you don't want to affect
"/guest," which you are using for another purpose, then
your script might look like the following (assuming the text you
are changing is already in $_):
<BLOCKQUOTE>
<PRE>
s/\\(.)/"\376".ord($1)."\377"/eg;
s/guest/member/g;
s/\376(\d+)\377/pack(C,$1)/e.g.;
</PRE>
</BLOCKQUOTE>
<P>
where every occurrence of the word "guest" is replaced
with "member."
<H3><A NAME="ProcessingAlltheElementsofanAssociativeArray">
Processing All the Elements of an Associative Array</A></H3>
<P>
Just like processing all the elements of an array, you may also
want to perform an operation on all the elements of an associative
array. This is done by the following procedure:
<BLOCKQUOTE>
<PRE>
foreach (sort keys %array_name) {
statement1;
statement2;
}
</PRE>
</BLOCKQUOTE>
<P>
The associative array is sorted in ascending value of the keys
using sort (if this operator is left out, the associative
array will be processed in the order it is found) and the operation
being applied to each element in the associative array is done
by statement1 and statement2.
<P>
If you wanted to find out your environmental variables, and have
them output in order, you could use this script:
<BLOCKQUOTE>
<PRE>
foreach (sort keys %env) {
print "$_ = $env{$_}\n"
}
</PRE>
</BLOCKQUOTE>
<P>
where your list of environmental variables is already in %env.
<H4>Prepending Block Labels to Consecutive Lines</H4>
<P>
This procedure takes consecutive lines of text and tacks on, or
prepends, a label to them, until the next label is found. The
format for the procedure looks like this:
<BLOCKQUOTE>
<PRE>
$label_name = initial_value;
while (<READ>) {
if (/:$) {
$label_name = $';
} else {
print WRITE $label_name, SEPARATOR, $_;
}
}
</PRE>
</BLOCKQUOTE>
<P>
where initial_value is a string expression with the initial value
for $label_name. The consecutive lines are taken from the source
specified by READ, the destination of these prepended lines is
WRITE, and each line is separated by the separator string SEPARATOR.
The default label is the "." symbol.
<P>
A common problem when working in Windows is that the .html extension
is often chopped to .htm, which will still work on some servers,
but when embedding hypertext links in your Web pages it can cause
problems. If your link says to go to index.html, but Windows chops
the filename to .htm, your link will not work. You could take
a list of your HTML files and pass them through this procedure,
with a check to see if the file already has the full .html extension,
as shown here:
<BLOCKQUOTE>
<PRE>
$ext = 'html';
while (<STDIN>) {
if (/:$/) {
$ext = $_';
} else {
print '.', $_, $ext;
}
}
</PRE>
</BLOCKQUOTE>
<P>
The new names are printed with .html attached, unless they already
have .html.
<H4>Making Long Numbers the Proper Format</H4>
<P>
If you are presenting long numbers with your script,<B> </B>then
you will want to have appropriately inserted commas every three
digits. Perl does not automatically make breaks in any numbers,
but runs them together if they are output to the screen.
<P>
You can make the necessary breaks by using a subroutine that matches
any string ending with four digits, takes the last three and places
them into $2, and puts the former string into $1, as shown in
the following:
<BLOCKQUOTE>
<PRE>
sub commas {
local($_) = @_;
1 while s/(.*\d)(\d\d\d)/$1,$2/;
$_;
}
statement1;
statement2;
$new_number = &commas(output_variable)
</PRE>
</BLOCKQUOTE>
<P>
The body statements after the while loop (statement1 and statment2)
define the numbers which are to be processed; output_variable
is the variable expression that holds the value of each number
to be modified; and $new_number holds the modified number.
<P>
As an example, you might want to insert commas into the results
of a lottery draw. You could do this by modifying the code above
to this one:
<BLOCKQUOTE>
<PRE>
sub commas {
local($_) = @_;
1 while s/(.*/d)(/d/d/d)/$1,$2/;
$_;
}
for ($integer = 1ØØ; $integer <= 1Øe8; $integer *= 1Ø) {
$prizes = &commas($integer);
print "$prizes\n";
}
</PRE>
</BLOCKQUOTE>
<P>
All the prize amounts for the lottery, all numbers that are powers
of 10 less than 10e8 but greater than 100, are put into $prize.
<H4>Truncating a File</H4>
<P>
If you need to erase, or truncate, a file in your script for security
or memory reasons, it is done simply by using the truncate operator.
<BLOCKQUOTE>
<PRE>
truncate ('answers.txt',Ø);
</PRE>
</BLOCKQUOTE>
<P>
where answers.txt is the file being truncated. When a file is
truncated, Perl is reducing its file to a length of zero, effectively
emptying the file.
<H2><A NAME="Conclusion"><FONT SIZE=5 COLOR=#FF0000>
Conclusion</FONT></A></H2>
<P>
The procedures covered here are only the most obvious examples
of what you will be able to do with Perl in your own scripts.
The methods of manipulating the different elements of your script-sorting,
processing, and others-are not limited to the procedures listed
here. There are many other ways to affect the data involved with
your script. Operators other than the ones used here can be used
to process variables.
<P>
Using what you've learned with these procedures, it is time to
advance to full-length programs in Perl. You've covered how arrays
and regular expressions are used to manipulate strings and files
in small sections, but now you need to fit this into the bigger
picture. In the next two chapters we will work with full-length
Perl programs that are not only useful for running a Web server,
but they can also teach you to solve more problems with Perl.
<HR>
<CENTER><P><A HREF="ch4.htm" tppabs="http://210.32.137.15/ebook/PC%20Magazine%20Programming%20Perl%205.0%20CGI%20Web%20Pages%20for%20Microsoft%20Windows%20NT/ch4.htm"><IMG SRC="PC.GIF" tppabs="http://210.32.137.15/ebook/PC%20Magazine%20Programming%20Perl%205.0%20CGI%20Web%20Pages%20for%20Microsoft%20Windows%20NT/PC.GIF" BORDER=0 HEIGHT=88 WIDTH=140></A>
<A HREF="#CONTENTS"><IMG SRC="CC.GIF" tppabs="http://210.32.137.15/ebook/PC%20Magazine%20Programming%20Perl%205.0%20CGI%20Web%20Pages%20for%20Microsoft%20Windows%20NT/CC.GIF" BORDER=0 HEIGHT=88 WIDTH=140></A>
<A HREF="contents.htm" tppabs="http://210.32.137.15/ebook/PC%20Magazine%20Programming%20Perl%205.0%20CGI%20Web%20Pages%20for%20Microsoft%20Windows%20NT/contents.htm"><IMG SRC="HB.GIF" tppabs="http://210.32.137.15/ebook/PC%20Magazine%20Programming%20Perl%205.0%20CGI%20Web%20Pages%20for%20Microsoft%20Windows%20NT/HB.GIF" BORDER=0 HEIGHT=88 WIDTH=140></A>
<A HREF="ch6.htm" tppabs="http://210.32.137.15/ebook/PC%20Magazine%20Programming%20Perl%205.0%20CGI%20Web%20Pages%20for%20Microsoft%20Windows%20NT/ch6.htm"><IMG SRC="NC.GIF" tppabs="http://210.32.137.15/ebook/PC%20Magazine%20Programming%20Perl%205.0%20CGI%20Web%20Pages%20for%20Microsoft%20Windows%20NT/NC.GIF" BORDER=0 HEIGHT=88 WIDTH=140></A>
<HR WIDTH="100%"></P></CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -