Expressing AND, OR, and NOT in a Single Pattern


You have an existing program that accepts a pattern as an argument or input. It doesn’t allow you to add extra logic, like case insensitive options, ANDs, or NOTs. So you need to write a single pattern that matches either of two different patterns (the “or” case), both of two patterns (the “and” case), or that reverses the sense of the match (“not”).

This situation arises often in a configuration files, web forms, or command-line arguments. Imagine there’s a program that does this:

chomp($pattern = <CONFIG_FH>);
if ( $data =~ /$pattern/ ) { ..... }

As the one maintaining the contents of CONFIG_FH, you need to convey Booleans through to the matching program through that one, measly pattern without explicit connectives.


True if either /ALPHA/ or /BETA/ matches, like /ALPHA/ || /BETA/:


True if both /ALPHA/ and /BETA/ match, but may overlap, meaning "BETALPHA" should be okay, like /ALPHA/ && /BETA/:


True if both /ALPHA/ and /BETA/ match, but may not overlap, meaning that "BETALPHA" should fail:


True if pattern /PAT/ does not match, like $var !~ /PAT/:


True if pattern BAD does not match, but pattern GOOD does:



When you’re writing a regular program and want to know if something doesn’t match, say one of:

if (!($string =~ /pattern/)) { something() } # ugly if ( $string !~ /pattern/) { something() } # preferred ...

Get Perl Cookbook now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.