Regular Expressions

A regular expression is a pattern that a string is searched for. Unix commands such as "ls *.*" are similar to regular expressions, but the syntax of regular expressions is more elaborated. Several Unix programs (grep, sed, awk, ed, vi, emacs) use regular expressions and many modern programming languages (such as Java) also support them.

$line =~/the /
searches for the occurrence of the four character sequence "the " in the string in $line. If "!~" was used instead of "=~" then the script would search for strings that do not contain the four character sequence "the ".

Example:

#!/usr/local/bin/perl
#
# Regular expressions
#
# reading a file:
open(ALICE, "alice.txt");
@lines = <ALICE> ;
close(ALICE);

# searching the file content line by line:
foreach $line (@lines){
    if ($line =~/the /){
        print $line;
    } # end of if
} # end of foreach

Exercises

List of special characters

1) Retrieve all lines from alice.txt that do not contain /the /. Retrieve all lines that contain "the" with lower or upper case letters (hint: use the ignore case option).

2) a) Retrieve lines that contain a three letter string consisting of "t", then any character, then "e", such as "the dog", "tree", "not ever".
b) Retrieve lines with a three letter word that starts with t and ends with e.
c) Retrieve lines that contain a word of any length that starts with t and ends with e. Modify this so that the word has at least three characters.
d) Retrieve lines that start with a. Retrieve lines that start with a and end with n.
e) Retrieve blank lines. Think of at least two ways of doing this.
f) Retrieve lines that have two consecutive o's.
g) Retrieve lines that do not contain the blank space character.
h) Retrieve lines that contain more than one blank space character.

3) For the following regular expressions write a script that lets a user input a string. The string is then compared to a regular expression (using =~). A message is printed to the screen if the match was successful. (Alternatively you could keep using the alice.txt file and simply add a couple of lines to it that contain these patterns.)

Match the following patterns:

a) an odd digit followed by an even digit (eg. 12 or 74)
b) a letter followed by a non-letter followed by a number
c) a word that starts with an upper case letter
d) the word "yes" in any combination of upper and lower cases letters
e) one or more times the word "the"
f) a date in the form of one or two digits, a dot, one or two digits, a dot, two digits
g) a punctuation mark

4) What is the difference between the following expressions?

a) abc* and (abc)*
b) !/yes/ and /[^y][^e][^s]/
c) [A-Z][a-z]* and [A-Z][a-z]+

5) Write a script that asks users for their name, address and phone number. Test each input for accuracy, for example, there should be no letters in a phone number (let's ignore that that's not always true in this country). A phone number should have a certain length. An address should have a certain format, etc. Ask the user to repeat the input in case your script identfies it as incorrect.

6) Concerning your projects: what kind of checking is needed to ensure that users fill in the forms in a sensible manner? Make certain that your form can handle all kinds of input. For example, users can have several first names, middle initials, several last names (which may or may not be hyphenated).

Special Characters

. Any single character except a newline
^ The beginning of the line or string
$ The end of the line or string
* Zero or more of the last character
+ One or more of the last character
? Zero or one of the last character
{5,10} Five to ten times the previous character
for example: * equals {0, }; + equals {1, }
? equals {0,1}

More special characters

[qjk] Either q or j or k
[^qjk] Neither q nor j nor k
[a-z] Anything from a to z inclusive
[^a-z] No lower case letters
[a-zA-Z] Any letter
[a-z]+ Any non-zero sequence of lower case letters
jelly|cream Either jelly or cream
(eg|le)gs Either eggs or legs
(da)+ Either da or dada or dadada or...
\n A newline
\t A tab
\w Any alphanumeric (word) character.
The same as [a-zA-Z0-9_]
\W Any non-word character.
The same as [^a-zA-Z0-9_]
\d Any digit. The same as [0-9]
\D Any non-digit. The same as [^0-9]
\s Any whitespace character: space,
tab, newline, etc
\S Any non-whitespace character
\b A word boundary, outside [] only
\B No word boundary

Escapes for special characters

\| Vertical bar
\[ An open square bracket
\) A closing parenthesis
\* An asterisk
\^ A carat symbol
\/ A slash
\\ A backslash

Optional: using the $_ variable

An alternative to the search script from above uses the $_ variable for the current line. It reads the file line by line (as opposed to storing it in an array). In this case the negation would be expressed as !/the /.

#!/usr/local/bin/perl
#
# Regular expressions
#
open(ALICE, "alice.txt");
while (<ALICE>){
    if (/the /){
        print $_;
    } # end of if
} # end of while
close(ALICE);