Perl has three different pattern-matching operators:
- One for matching
- One for substitution (search and replace)
- One for character translation
These operators work with regular expressions, which are covered in detail in the next module, and give you the power to search and replace within text. We will concentrate on the syntax of the operators over the next several lessons, along with just enough detail to allow you to understand their use.
- Match operator:
The match operator (m/
pattern/
) is usually written without the m
, like this:
/pattern/
. Just like the quote operators, you can use any characters to delimit the pattern, but you must use /
characters if you want to omit the m
.
# matches "foo/bar", which has a / in it
m(foo/bar)
The pattern is a regular expression, but it can be simply the text you want to search for. Here is a simple program that prints all the lines in a file that have the word
hello in them.
#!/usr/bin/perl -w
while(<>) {
print if /hello/i;
}
Run that program with a filename (or filenames) on the command line, and it will print only the lines that have the word
hello in them.
Notice the
i
character right after the match operator. This is one of
several switches that you can use. In the next lesson, we will cover the substitute operator.
Perl Match Operator Switches
Switch | Meaning |
i | Ignore case |
g | Match globally, that is, find all occurrences, not just the first one |
m | Treat the string as multiple lines |
o | Only compile the pattern once |
s | Treat the string as a single line |
x | Use extended regular expressions |
For now, the
i
switch is the only one that's important. The rest of them will be covered in the next module.
At times, you might like to include a pattern component in your pattern without including it in the $&
variable that holds the matched string. The technical term for this is a zero-width positive look-ahead assertion. You can use this to ensure that the string following the matched component is correct without affecting the matched value. For example, if you have some data that looks like this:
David Veterinarian 56
Jackie Orthopedist 34
Karen Veterinarian 28
and you want to find all veterinarians and store the value of the first column, you can use a look-ahead assertion.
This will do both tasks in one step. For example
while (<>) {
push(@array, $&) if m/^\w+(?=\s+Vet)/;
}
print("@array\n");
This program will display
David Karen
Let us look at the pattern with comments added using the extended mode. In this case, it does not make sense to add comments directly to the pattern because the pattern is part of the if statement modifier. Adding comments in that location would make the comments hard to format. So let us use a different tactic
$pattern = '^\w+ (?# Match the first word in the string)
(?=\s+ (?# Use a look-ahead assertion to match)
(?# one or more whitespace characters)
Vet) (?# In addition to the whitespace, make)
(?# sure that the next column starts)
(?# with the character sequence "Vet")
';
while (<>) {
push(@array, $&) if m/$pattern/x;
}
print("@array\n");
Here we used a variable to hold the pattern and then used variable interpolation in the pattern with the match operator.
You might want to pick a more descriptive variable name than $pattern, however.