## With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

No credit card required

# Expressing AND, OR, and NOT in a Single Pattern

## Problem

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.

## Solution

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

`/ALPHA|BETA/`

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

`/^(?=.*ALPHA)(?=.*BETA)/s`

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

`/ALPHA.*BETA|BETA.*ALPHA/s`

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

`/^(?:(?!PAT).)*\$/s`

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

`/(?=^(?:(?!BAD).)*\$)GOOD/s`

## Discussion

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 ...`

## With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

No credit card required