We have learnt how to store scalar variables and arrays. In this lab,
we shall see the third useful data structure: Associative arrays (hashes).
Also, since the power of perl is in manipulation of strings for generating
reports, or HTML files, we will learn the most common string manipulation
utilities. In particular, we concentrate on the following:
1. Joining Strings using the "." operator
2. Matching (searching) for patterns in a string using m/PATTERN/
3. Substituting (find/replace) one expression for another using s/OLD/NEW/
#!/usr/local/bin/perl $a_string = "Perl is simple."; $b_string = "I love it!"; $join_string = $a_string . $b_string; print $join_string; print "\n"; # the '.' operator can be used many times, with variable or constant strings: $nicer = $a_string . " " . $b_string; print $nicer; print "\n";
NOTES:
When you want to join two strings, use the dot operator, ".", as in this
example. Recall that you can break any string using the split
function.
#!/usr/local/bin/perl
$line = <STDIN>;
chop ($line);
@words = split(/[ \t]+/, $line);
$index = 0;
while ( $index < @words) {
print ("$words[$index]\n");
$index++;
}
print( "\n");
NOTES:
This is a useful example. Here, the split function works as
follows:
It searches for any character between the square brackets. In the example,
there are two characters inside '[' and ']': " " (space), and '\t' (tab).
The '+' sign following the square brackets is used to indicate
one or more consecutive occurences of any characters inside
the '[' and ']'. In this case, the variable $line will be split wherever
there is any combination of spaces and tabs.
#!/usr/local/bin/perl
$_ = "Bus 298 goes to Lam Tin every 20 minutes";
if ( m/Lam Tin/) {
print ("Found a bus to Lam Tin !\n");
}
else { print ( "No bus to Lam Tin.\n"); }
if ( m/Choi Hung/) {
print ("Found a bus to Choi Hung.\n");
}
else { print ( "No bus to Choi Hung.\n"); }
NOTES:
The matching operator, m/PATTERN/ will return TRUE if PATTERN matches a patern
in a variable called $_. The $_ is a special variable which is used for all
pattern matches for the mathing (m//) and substitute (s///) operators.
The match operator can use UNIX regular expression syntax modifiers. Most
useful are the following:
m/PATTERN/g will do a Global search (find all occurences) of PATTERN in the
variable $_. since there ma be more than one matches, it returns an array,
with each successful match as elements.
m/PATTERN/i will Ignore the case (lower case, upper case) when matching.
You can use the 'i' and 'g' specifications together also, as in the next
example.
#!/usr/local/bin/perl
$_ = "UPPER CASE ? lower case ? Mixed CaSe ? No Problem !";
@case_instances = m/case/ig;
foreach $c (@case_instances) {
print ("$c \n");
}
NOTES:
1. The use of "i" ignores the case while matching.
2. The use of "g" causes Global match (every instance); Note also that the
match operator can be used to directly return an array !
3. Some useful matching patterns include matching word characters (any
alphanumeric character, or the underscore) using \w, multiple word characters
(that is, a single word) using \w+, single space character using \s, non-word
characters (punctuation marks) using \W, tabs using \t, newline using \n
etc.
#!/usr/local/bin/perl $_ = "I love Jackie Chan movies! I love kung-fu movies."; print "$_ \n"; s/love/HATE/; print( "$_ \n"); s/(HATE|love)/Admire/g; print( "$_ \n"); s/admire/dislike/ig; print( "$_ \n"); s/dis//g; print( "$_ \n");
NOTES:
This example shows several features of the substitute operator.
1. Just like the match operator, the substitution is done on the
value of a variable called $_.
2. The s/OLD/NEW/ will replace the FIRST OCCURENCE of "OLD" with "NEW".
3. The vertical bar, "|", is used to denote alternatives. It may be used many
times in the same expression.
4. As for the match operator, you may use "g" and "i" filters.
5. Notice how "s/dis//g works: Every occurence of pattern "dis" is replaced by
a null string.
#!/usr/local/bin/perl
print ( "Enter a short password: ");
system ( "stty -echo");
# read the password, but it will not be printed to the screen !
$password = <STDIN>;
chop( $password);
print( "\nTo turn on the screen, type the password again: ");
$password_match = 0;
$n_tries = 0;
while ( ($n_tries < 3) && ($password_match == 0)) {
$trial = <STDIN>;
chop ($trial);
if ($trial eq $password) { $password_match = 1;}
else { print( "\nPassword does not match. Please re-type: "); }
$n_tries++;
}
if ($password_match == 1) {
print( "\nPassword matches !\n");
}
else {
print( "\nSorry, your password was not correct !\n");
}
system( "stty echo");
NOTES:
1. Notice that ANY unix function can be called from perl, using:
system ( "UNIX-function-name arguments")
2. In this case, we call a Unix function: "stty", with argument "-echo".
stty can be used to set terminal characteristics. With the argument
"-echo", it causes the effect that what you type will not be printed on the
screen.
3. Note that other functions can still print output to the screen; therfore
the call to print still works after terminal echo is turned off.
However, at the end of the program, if you do not turn terminal echo ON again
(using "stty echo"), Unix may not show what you type on the screen after your
program has completed execution.
#!/usr/local/bin/perl
%hobbies = ( "ajay", "tennis",
"ivan", "basketball",
"william", "swimming");
print ("Ivan's hobby is: ", $hobbies{"ivan"}, "\n");
# this is a nice way to format the printing of a hash:
while ( ($key, $value) = each %hobbies) {
print "$key = $value\n";
}
# this is how you set new values into a hash:
$hobbies{"jack"} = "soccer";
# this is how you delete a KEY (and its VALUE) from a hash:
delete $hobbies{"ajay"};
# and check if it works:
print "\nThe modified hash values are:\n";
while ( ($key, $value) = each %hobbies) {
print "$key = $value\n";
}
NOTES:
1. We have learnt storing scalar variables (numbers, strings...) in
$variable.
We also saw how to store an array of variables in @array.
Here, we see the third useful structure for storing data, an associative
array (also called a 'hash').
2. You can think of a hash as an array, with the following difference:
an array is a list of variables, each with a name that looks like: array[i],
where 'i' is the subscript value, such as 0, 1, 2, ...etc.
A hash is a list of variables, with specific names (also called 'keys'). Each
'key' has an associatee value. The hash is stored as follows:
( Key1, Value-Of-Key1, Key2, Value-of-Key2, ..., KeyN, Value-of-KeyN).
If you want to get the value of 'Key5' from the hash called "%myHash", you
must urefer to: $myHash{ "Key5"}
For example, in the example, the key "ajay" has value "tennis", while the key
"ivan" has the value "basketball".
3. When you work with the output of a database, you wil store the resulting
table in an array; when you work with inputs from a FORM, you will store the
values of these inputs in a hash.
Therefore, arrays and hashes are the most useful structures for writing cgi's linked to databases.
(e) Ask the user to enter a course name;
(f) If the instructor's name for this course contains the string "aj" (ignore
case when matching) , print "This is a fun course";
otherwise print "I prefer DB!".
2. First create a file called nba.txt with the following contents:
Player Team =============================== Grant Hill Pistons Shaquille Oneal Lakers Karl Malone Jazz Chris Webber Sixers Allen Iverson Kings Gary Payton Sonics Sharif Abdur Rahim Grizzlies