Lecture Notes Six: Circular scripts (Part II). Pattern matching in Perl.

19. Let's now move to the second problem, with one (a suddenly simple program).

#!/usr/bin/perl

&printTop; print "Hello!"; &printBottom; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
20. So far so good.

21. What do we add in two to it?

#!/usr/bin/perl

&printTop; 

$name = $ENV{"SCRIPT_NAME"}; 

$method = $ENV{REQUEST_METHOD};

print "Hello, I am  $name, and I am called with method: $method. <p>"; 

&printBottom; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
22. This is three a bit reorganized for better focus.

#!/usr/bin/perl

&printTop; $name = $ENV{"SCRIPT_NAME"}; $method = $ENV{REQUEST_METHOD};
print "Hello, I am  $name, and I am called with method: $method. <p>"; 
&printBottom; 

print qq{
  <form method="$method" action="$name"> 
     Argument: <input type="text" name="arg"> <p>
     Function: <select name="fun"> 
       <option value="non"> Click Me!
       <option value="add"> Addition
       <option value="sub"> Subtraction 
     </select> <p>
     <input type="submit" value="Proceed">      
  </form>
}; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
23. Let's make a change (four) and experiment.

#!/usr/bin/perl

&printTop; $name = $ENV{"SCRIPT_NAME"}; $method = $ENV{REQUEST_METHOD};
print "Hello, I am  $name, and I am called with method: $method. <p>"; 
&printBottom; 

print "(", $ENV{"QUERY_STRING"}, ")<p>"; 

print qq{
  <form method="$method" action="$name"> 
     Argument: <input type="text" name="arg"> <p>
     Function: <select name="fun"> 
       <option value="non"> Click Me!
       <option value="add"> Addition
       <option value="sub"> Subtraction 
     </select> <p>
     <input type="submit" value="Proceed">      
  </form>
}; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
24. Is your calculator working already?

25. Are we getting any closer?

26. Perhaps we should take a break?

27. Nope, we should keep going.

28. Here's five, taking the input apart.

#!/usr/bin/perl

&printTop; $name = $ENV{"SCRIPT_NAME"}; $method = $ENV{REQUEST_METHOD};
print "Hello, I am  $name, and I am called with method: $method. <p>"; 
&printBottom; 

$input = $ENV{"QUERY_STRING"}; 

print "($input)<p>"; 

@pairs = split(/&/, $input); 

foreach $pair (@pairs) {
  print "($pair)<p>"; 
} 

print qq{
  <form method="$method" action="$name"> 
     Argument: <input type="text" name="arg"> <p>
     Function: <select name="fun"> 
       <option value="non"> Click Me!
       <option value="add"> Addition
       <option value="sub"> Subtraction 
     </select> <p>
     <input type="submit" value="Proceed">      
  </form>
}; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
29. But that's only part of it.

30. The next one (six) does the rest of the work.

#!/usr/bin/perl

&printTop; $name = $ENV{"SCRIPT_NAME"}; $method = $ENV{REQUEST_METHOD};
print "Hello, I am  $name, and I am called with method: $method. <p>"; 
&printBottom; 

$input = $ENV{"QUERY_STRING"}; 

print "($input)<p>"; 

@pairs = split(/&/, $input); 

foreach $pair (@pairs) {
  print "($pair)<p>"; 
  ($nam, $val) = split(/=/, $pair); 
  print qq{
    Name is ($nam) and value is ($val). <p> 
  }
} 

print qq{
  <form method="$method" action="$name"> 
     Argument: <input type="text" name="arg"> <p>
     Function: <select name="fun"> 
       <option value="non"> Click Me!
       <option value="add"> Addition
       <option value="sub"> Subtraction 
     </select> <p>
     <input type="submit" value="Proceed">      
  </form>
}; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
31. The next program (seven) not only takes the input apart in the same manner as six, it also carefully records the input in a hash table, for future use, and gets prepared for its role as a calculator.

#!/usr/bin/perl

&printTop; $name = $ENV{"SCRIPT_NAME"}; $method = $ENV{REQUEST_METHOD};
print "Hello, I am  $name, and I am called with method: $method. <p>"; 
&printBottom; 

$input = $ENV{"QUERY_STRING"}; 

print "($input)<p>"; 

@pairs = split(/&/, $input); 

foreach $pair (@pairs) {
  print "($pair)<p>"; 
  ($nam, $val) = split(/=/, $pair); 
  print qq{
    Name is ($nam) and value is ($val). <p> 
  };
  $form{$nam} = $val; 
} 

foreach $key (keys %form) {
  print "($key) is associated with (", $form{$key}, ")<p>"; 
} 

if ($form{fun} eq "add") {

} elsif ($form{fun} eq "sub") {

} else {
  
} 

print qq{
  <form method="$method" action="$name"> 
     Argument: <input type="text" name="arg"> <p>
     Function: <select name="fun"> 
       <option value="non"> Click Me!
       <option value="add"> Addition
       <option value="sub"> Subtraction 
     </select> <p>
     <input type="submit" value="Proceed">      
  </form>
}; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
32. Are we getting any closer?

#!/usr/bin/perl

&printTop; $name = $ENV{"SCRIPT_NAME"}; $method = $ENV{REQUEST_METHOD};
print "Hello, I am  $name, and I am called with method: $method. <p>"; 
&printBottom; $input = $ENV{"QUERY_STRING"}; print "($input)<p>"; 

@pairs = split(/&/, $input); 

foreach $pair (@pairs) {
  ($nam, $val) = split(/=/, $pair); 
  $form{$nam} = $val; 
} 

if ($form{fun} eq "add") {
  $acc = $acc + $form{arg}; 
} elsif ($form{fun} eq "sub") {
  $acc = $acc - $form{arg};
} else {
  
} 

print qq{
  <form method="$method" action="$name"> 
     Accumulator is: ($acc) <p> 
     Argument: <input type="text" name="arg"> <p>
     Function: <select name="fun"> 
       <option value="non"> Click Me!
       <option value="add"> Addition
       <option value="sub"> Subtraction 
     </select> <p>
     <input type="submit" value="Proceed">      
  </form>
}; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
33. The program above (eight) is trying. What's missing?

34. How's nine handling this problem?

#!/usr/bin/perl

&printTop; $name = $ENV{"SCRIPT_NAME"}; $method = $ENV{REQUEST_METHOD};
print "Hello, I am  $name, and I am called with method: $method. <p>"; 
&printBottom; $input = $ENV{"QUERY_STRING"}; print "($input)<p>"; 

@pairs = split(/&/, $input); 

foreach $pair (@pairs) {
  ($nam, $val) = split(/=/, $pair); 
  $form{$nam} = $val; 
} 

$acc = $form{acc}; 

if ($form{fun} eq "add") {
  $acc = $acc + $form{arg}; 
} elsif ($form{fun} eq "sub") {
  $acc = $acc - $form{arg};
} else {
  
} 

print qq{
  <form method="$method" action="$name"> 
     Accumulator is: ($acc) <p>
     Field named acc containg the accumulator value: 
         <input type="text" value="$acc" name="acc"> <p>  
     Argument: <input type="text" name="arg"> <p>
     Function: <select name="fun"> 
       <option value="non"> Click Me!
       <option value="add"> Addition
       <option value="sub"> Subtraction 
     </select> <p>
     <input type="submit" value="Proceed">      
  </form>
}; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
35. In ten we change one word only.

#!/usr/bin/perl

&printTop; $name = $ENV{"SCRIPT_NAME"}; $method = $ENV{REQUEST_METHOD};
print "Hello, I am  $name, and I am called with method: $method. <p>"; 
&printBottom; $input = $ENV{"QUERY_STRING"}; print "($input)<p>"; 

@pairs = split(/&/, $input); 

foreach $pair (@pairs) {
  ($nam, $val) = split(/=/, $pair); 
  $form{$nam} = $val; 
} 

$acc = $form{acc}; 

if ($form{fun} eq "add") {
  $acc = $acc + $form{arg}; 
} elsif ($form{fun} eq "sub") {
  $acc = $acc - $form{arg};
} else {
  
} 

print qq{
  <form method="$method" action="$name"> 
     Accumulator is: ($acc) <p>
     Field named acc containg the accumulator value: 
         <input type="hidden" value="$acc" name="acc"> <p>  
     Argument: <input type="text" name="arg"> <p>
     Function: <select name="fun"> 
       <option value="non"> Click Me!
       <option value="add"> Addition
       <option value="sub"> Subtraction 
     </select> <p>
     <input type="submit" value="Proceed">      
  </form>
}; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
36. Can you see which one, and what the difference is?

37. What is the difference between GET and POST?

The program below (eleven) would be able to point it out to you.

#!/usr/bin/perl

&printTop; $name = $ENV{"SCRIPT_NAME"}; $method = $ENV{REQUEST_METHOD};
print "Hello, I am  $name, and I am called with method: $method. <p>"; 
&printBottom; 

if ($method eq "GET") {
  $input = $ENV{"QUERY_STRING"}; 
} else {
  read(STDIN, $input, $ENV{"CONTENT_LENGTH"}); 
}

print "($input)<p>"; 

@pairs = split(/&/, $input); 

foreach $pair (@pairs) {
  ($nam, $val) = split(/=/, $pair); 
  $form{$nam} = $val; 
} 

$acc = $form{acc}; 

if ($form{fun} eq "add") {
  $acc = $acc + $form{arg}; 
} elsif ($form{fun} eq "sub") {
  $acc = $acc - $form{arg};
} else {
  
} 

print qq{
  <form method="POST" action="$name"> 
     Accumulator is: ($acc) <p>
     Field named acc containg the accumulator value: <input type="hidden"
value="$acc" name="acc"> <p>  
     Argument: <input type="text" name="arg"> <p>
     Function: <select name="fun"> 
       <option value="non"> Click Me!
       <option value="add"> Addition
       <option value="sub"> Subtraction 
     </select> <p>
     <input type="submit" value="Proceed">      
  </form>
}; 

sub printTop {
  print qq{Content-type: text/html\n\n<html>
    <head><title>My Pictures Script</title></head>
    <body bgcolor=white>
  }; 
} 

sub printBottom {
  print qq{</body></html>}; 
}
38. Are we any closer now?

39. Can you write the two programs?

40. I am sure you can.

41. If you have any questions please let me know!

Let's now look at pattern matching.

Perhaps we will get to these only next week.

But I'd like to have them mentioned here even before.

We're using the =~ operator, together with the letter s on its right hand side, followed by a slash delimited pattern to be matched, and a string. When the pattern matches the string that follows the second slash will replace it. There are several rules and exceptions and we will summarize those that we care for here, through a couple of examples.

The dot (.) matches any one character except newline.

frilled.cs.indiana.edu%cat alpha
#!/usr/bin/perl
$a = "1234567890"; 
$a =~ s/./a/; 
print $a; 
frilled.cs.indiana.edu%./alpha
a234567890frilled.cs.indiana.edu%
To have the substitution happen everywhere it can happen, use g (global) aftre the third slash.

frilled.cs.indiana.edu%cat alpha
#!/usr/bin/perl
$a = "1234567890"; 
$a =~ s/./a/g; 
print $a; 
frilled.cs.indiana.edu%./alpha
aaaaaaaaaafrilled.cs.indiana.edu%
The pattern can be bigger (or longer):
frilled.cs.indiana.edu%cat alpha
#!/usr/bin/perl
$a = "1234567890"; 
$a =~ s/../a/g; 
print $a; 
frilled.cs.indiana.edu%./alpha
aaaaafrilled.cs.indiana.edu%
Parentheses can be used as memory elements:

frilled.cs.indiana.edu%cat alpha
#!/usr/bin/perl
$a = "1234567890"; 
$a =~ s/(.)(.)/$2$1/g; 
print $a; 
frilled.cs.indiana.edu%./alpha
2143658709frilled.cs.indiana.edu%
And they can include larger patterns:
frilled.cs.indiana.edu%cat alpha
#!/usr/bin/perl
$a = "1234567890"; 
$a =~ s/(..)/$1+1/g; 
print $a; 
frilled.cs.indiana.edu%./alpha
12+134+156+178+190+1frilled.cs.indiana.edu%
To have the part between the last two slashes act as Perl code use e (evaluate) after the third slash.

frilled.cs.indiana.edu%cat alpha
#!/usr/bin/perl
$a = "1234567890"; 
$a =~ s/(..)/$1+1/ge; 
print $a; 
frilled.cs.indiana.edu%./alpha
1335577991frilled.cs.indiana.edu%
Miscellaneous

A few other things needed in ReadParse (for next week) are listed below.

Characters have (decimal) ASCII codes that can be obtain with ord.

frilled.cs.indiana.edu%cat alpha
#!/usr/bin/perl
@values = ('A', 'B', 'C', 'D', 'E'); 
foreach $value (@values) {
  print $value, " has ASCII code: ", ord($value), "\n"; 
} 
frilled.cs.indiana.edu%./alpha
A has ASCII code: 65
B has ASCII code: 66
C has ASCII code: 67
D has ASCII code: 68
E has ASCII code: 69
frilled.cs.indiana.edu%
ASCII codes can be turned into characters with chr.

frilled.cs.indiana.edu%cat alpha
#!/usr/bin/perl
@values = (65, 66, 67, 68, 69); 
foreach $value (@values) {
  print "ASCII code $value stands for: ", chr($value), "\n"; 
} 
frilled.cs.indiana.edu%./alpha
ASCII code 65 stands for: A
ASCII code 66 stands for: B
ASCII code 67 stands for: C
ASCII code 68 stands for: D
ASCII code 69 stands for: E
frilled.cs.indiana.edu%
The hex function turns a hexadecimal value in a decimal one.

frilled.cs.indiana.edu%cat alpha
#!/usr/bin/perl
@values = (1, 10, 20, 100, 110, 111); 
foreach $value (@values) {
  print "$value in base 16 is equal to ", hex($value), " in base 10.\n"; 
} 
frilled.cs.indiana.edu%./alpha
1 in base 16 is equal to 1 in base 10.
10 in base 16 is equal to 16 in base 10.
20 in base 16 is equal to 32 in base 10.
100 in base 16 is equal to 256 in base 10.
110 in base 16 is equal to 272 in base 10.
111 in base 16 is equal to 273 in base 10.
frilled.cs.indiana.edu%

You're now ready for Tuesday.

Thank you.


Last updated: Sep 13, 2001 by Adrian German for A348/A548