Previous Table of Contents Next


Session 3
Matching

Regular expressions (Figure 2-5) can be used for more than just substitutions. And they don’t have to operate on $_, like every example you’ve seen so far. Regular expressions can be used simply to match strings, without replacing anything.


Figure 2-5  Regular expressions can simply identify matching substrings without replacing them

The m// operator matches a regular expression.


The m// Operator
m/REGEX/MODIFIERS is TRUE if $_ matches REGEX, and FALSE otherwise.

In a scalar context, every match returns a value: TRUE if the string ($_ by default) matched the regular expression, and FALSE otherwise. In an array context, m// returns an array of all matching strings. See “Parentheses” later in this session, and the /g modifier. /g, /i, /m, /o, /s, and /x are all optional modifiers discussed later in this chapter.

Like s///, m// lets you use different delimiters.

m!flurgh!

matches flurgh.

m@.\s.@

matches any character, followed by whitespace, followed by any character.

m#90?#

matches 9 and 90.

You can use any nonalphanumeric, non-whitespace character except ?, which has a special meaning (described in Chapter 4, Session 5). But you should use / whenever you can, just because that’s what everyone else does. m// encourages this practice by letting you omit the m if you use / as the delimiter.

/.\./

matches any character, followed by a period.

if (/flag/) { $sentiment++; }

increments $sentiment if $_ contains flag.

print "Spacey" if /\s/;

prints spacey if $_ contains whitespace.

All of the examples you’ve seen so far for s/// and m// apply regexes to $_. You can specify other scalars with the =~ and !~ operators.


The =~ and !~ Operators
STRING =~ m/REGEX/ is TRUE if STRING matches REGEX.
STRING !~ m/REGEX/ is TRUE if STRING does not match REGEX.
STRING =~ s/REGEX/STRING/ replaces occurrences of REGEX with STRING.

When used with m//, =~ resembles the equality operators == and eq because it returns TRUE if the string on the left matches its regex and FALSE otherwise. Used with s///, it behaves more like = and actually performs the substitution on the string.

Some examples:

if ($answer =~ /yes/) { print "Good"; }

prints Good if $answer contains yes.

$line =~ s/ //g if $line ~= /.{80,}/;

removes consecutive whitespace from $line if it has more than 80 characters.

$string =~ s/coffee/tea/;

replaces the first occurrence of coffee with tea in $string.

print "That has no digits!" if $string !~ /\d/;

prints That has no digits! if $string contains no digits.

The program shown in Listing 2-7, agree, uses=~ to identify whether the user typed yes or no.

Listing 2-7 agree: Using =~ to determine if a scalar variable matches a pattern

#!/usr/bin/perl -w

print 'Yes or no? ';
chomp($answer = <>);
if ($answer =~ /y/) { # TRUE if $answer is y or yes or yeah or NO WAY.
    print "I'm glad you agree!\n";
}

Here’s agree in action:

% agree
RESULT: Yes or no? yup
I’m glad you agree!
% agree
RESULT: Yes or no? nope
% agreee
RESULT: Yes or no? oh yeah
I’m glad you agree!

Remember all those tickets programs from Chapter 1? Let’s make a new version, tickets6, that’s a bit more useful; this time, allow the user to specify a substring instead of having to supply the full movie title (Listing 2-8).


Previous Table of Contents Next